不相信人咬不到肚脐的,咬破肚脐去死如何? 收藏本站
登陆 / 注册 搜索

阅读: 10K   回复: 9

[# 加密解密] 加密算法说明(MD5、DES)

小执念 古黑浩劫论坛大牛 2015-11-18 00:30 |显示全部楼层

可遇不可求的事:故乡的云,上古的玉,随手的诗,十九岁的你。

管理员
DES

      DESData Encryption Standard(数据加密标准)的缩写。DES是一个分组加密算法,他以64位为分组对数据加密。同时DES也是一个对称算法:加密和解密用的是同一个算法。它的密匙长度是56位(因为每个第8位都用作奇偶校验),密匙可以是任意的56位的数,而且可以任意时候改变。其中有极少量的数被认为是弱密匙,但是很容易避开他们。所以保密性依赖于密钥。

      DES对64(bit)位的明文分组M进行操作,M经过一个初始置换IP置换成m0,将m0明文分成左半部分和右半部分m0=(L0,R0),各32位长。然后进行16轮完全相同的运算,这些运算被称为函数f,在运算过程中数据与密匙结合。经过16轮后,左,右半部分合在一起经过一个末置换,这样就完成了。在每一轮中,密匙位移位,然后再从密匙的56位中选出48位。通过一个扩展置换将数据的右半部分扩展成48位,并通过一个异或操作替代成新的32位数据,在将其置换换一次。这四步运算构成了函数f。然后,通过另一个异或运算,函数f的输出与左半部分结合,其结果成为新的右半部分,原来的右半部分成为新的左半部分。将该操作重复16次,就实现了。

      解密过程:在经过所有的代替、置换、异或盒循环之后,你也许认为解密算法与加密算法完全不同。恰恰相反,经过精心选择的各种操作,获得了一个非常有用的性质:加密和解密使用相同的算法。DES加密和解密唯一的不同是密匙的次序相反如果各轮加密密匙分别是K1,K2,K3….K16那么解密密匙就是K16,K15,K14…K1。

MD5

      MD5的全称是Message-Digest Algorithm5,Message-Digest泛指字节串(Message)的Hash变换,就是把一个任意长度的字节串变换成一定长的大整数。请注意我使用了"字节串"而不是"字符串"这个词,是因为这种变换只与字节的值有关,与字符集或编码方式无关。MD5将任意长度的"字节串"变换成一个128bit的大整数,并且它是一个不可逆的字符串变换算法,换句话说就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷多个,这有点象不存在反函数的数学函数。

      MD5的典型应用是对一段Message(字节串)产生fingerprint(指纹),以防止被"篡改"。举个例子,你将一段话写在一个叫wuai.txt 文件中,并对这个 wuai.txt 产生一个MD5的值并记录在案,然后你可以传这个文件给别人,别人如果修改了文件中的任何内容,你对这个文件重新计算MD5时就会发现。如果再有一个第三方的认证机构,用MD5还可以防止文件作者的"抵赖",这就是所谓的数字签名应用。

      MD5还广泛用于加密和解密技术上,在很多操作系统中,用户的密码是以MD5值(或类似的其它算法)的方式保存的,用户Login的时候,系统是把用户输入的密码计算成MD5值,然后再去和系统中保存的MD5值进行比较,而系统并不"知道"用户的密码是什么。

      一些黑客破获这种密码的方法是一种被称为"跑字典"的方法。有两种方法得到字典,一种是日常搜集的用做密码的字符串表,另一种是用排列组合方法生成的,先用MD5程序计算出这些字典项的MD5值,然后再用目标的MD5值在这个字典中检索。

      即使假设密码的最大长度为8,同时密码只能是字母和数字,共26+26+10=62个字符,排列组合出的字典的项数则是P(62,1)+P(62,2)....+P(62,8),那也已经是一个很天文的数字了,存储这个字典就需要TB级的磁盘组,而且这种方法还有一个前提,就是能获得目标账户的密码MD5值的情况下才可以。

      C++实现:

全屏查看
  1. #include<string>
  2. using namespace std;
  3. #define shift(x, n) (((x) << (n)) | ((x) >> (32-(n))))//右移的时候,高位一定要补零,而不是补充符号位
  4. #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))   
  5. #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
  6. #define H(x, y, z) ((x) ^ (y) ^ (z))
  7. #define I(x, y, z) ((y) ^ ((x) | (~z)))
  8. #define A 0x67452301
  9. #define B 0xefcdab89
  10. #define C 0x98badcfe
  11. #define D 0x10325476
  12. //strBaye的长度
  13. unsigned int strlength;
  14. //A,B,C,D的临时变量
  15. unsigned int atemp;
  16. unsigned int btemp;
  17. unsigned int ctemp;
  18. unsigned int dtemp;
  19. //常量ti unsigned int(abs(sin(i+1))*(2pow32))
  20. const unsigned int k[]={
  21.         0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
  22.         0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,0x698098d8,
  23.         0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,
  24.         0xa679438e,0x49b40821,0xf61e2562,0xc040b340,0x265e5a51,
  25.         0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
  26.         0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905,
  27.         0xfcefa3f8,0x676f02d9,0x8d2a4c8a,0xfffa3942,0x8771f681,
  28.         0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,
  29.         0xbebfbc70,0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
  30.         0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,0xf4292244,
  31.         0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,
  32.         0xffeff47d,0x85845dd1,0x6fa87e4f,0xfe2ce6e0,0xa3014314,
  33.         0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391};
  34. //向左位移数
  35. const unsigned int s[]={7,12,17,22,7,12,17,22,7,12,17,22,7,
  36.         12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
  37.         4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,
  38.         15,21,6,10,15,21,6,10,15,21,6,10,15,21};
  39. const char str16[]="0123456789abcdef";
  40. void mainLoop(unsigned int M[])
  41. {
  42.     unsigned int f,g;
  43.     unsigned int a=atemp;
  44.     unsigned int b=btemp;
  45.     unsigned int c=ctemp;
  46.     unsigned int d=dtemp;
  47.     for (unsigned int i = 0; i < 64; i++)
  48.     {
  49.         if(i<16){
  50.             f=F(b,c,d);
  51.             g=i;
  52.         }else if (i<32)
  53.         {
  54.             f=G(b,c,d);
  55.             g=(5*i+1)%16;
  56.         }else if(i<48){
  57.             f=H(b,c,d);
  58.             g=(3*i+5)%16;
  59.         }else{
  60.             f=I(b,c,d);
  61.             g=(7*i)%16;
  62.         }
  63.         unsigned int tmp=d;
  64.         d=c;
  65.         c=b;
  66.         b=b+shift((a+f+k<i>+M[g]),s<i>);
  67.         a=tmp;
  68.     }
  69.     atemp=a+atemp;
  70.     btemp=b+btemp;
  71.     ctemp=c+ctemp;
  72.     dtemp=d+dtemp;
  73. }
  74. /*
  75. *填充函数
  76. *处理后应满足bits≡448(mod512),字节就是bytes≡56(mode64)
  77. *填充方式为先加一个1,其它位补零
  78. *最后加上64位的原来长度
  79. */
  80. unsigned int* add(string str)
  81. {
  82.     unsigned int num=((str.length()+8)/64)+1;//以512位,64个字节为一组
  83.     unsigned int *strByte=new unsigned int[num*16];    //64/4=16,所以有16个整数
  84.     strlength=num*16;
  85.     for (unsigned int i = 0; i < num*16; i++)
  86.         strByte<i>=0;
  87.     for (unsigned int i=0; i <str.length(); i++)
  88.     {
  89.         strByte[i>>2]|=(str<i>)<<((i%4)*8);//一个整数存储四个字节,i>>2表示i/4 一个unsigned int对应4个字节,保存4个字符信息
  90.     }
  91.     strByte[str.length()>>2]|=0x80<<(((str.length()%4))*8);//尾部添加1 一个unsigned int保存4个字符信息,所以用128左移
  92.     /*
  93.     *添加原长度,长度指位的长度,所以要乘8,然后是小端序,所以放在倒数第二个,这里长度只用了32位
  94.     */
  95.     strByte[num*16-2]=str.length()*8;
  96.     return strByte;
  97. }
  98. string changeHex(int a)
  99. {
  100.     int b;
  101.     string str1;
  102.     string str="";
  103.     for(int i=0;i<4;i++)
  104.     {
  105.         str1="";
  106.         b=((a>>i*8)%(1<<8))&0xff;   //逆序处理每个字节
  107.         for (int j = 0; j < 2; j++)
  108.         {
  109.             str1.insert(0,1,str16[b%16]);
  110.             b=b/16;
  111.         }
  112.         str+=str1;
  113.     }
  114.     return str;
  115. }
  116. string getMD5(string source)
  117. {
  118.     atemp=A;    //初始化
  119.     btemp=B;
  120.     ctemp=C;
  121.     dtemp=D;
  122.     unsigned int *strByte=add(source);
  123.     for(unsigned int i=0;i<strlength/16;i+=16)
  124.     {
  125.         unsigned int num[16];
  126.         for(unsigned int j=0;j<16;j++)
  127.             num[j]=strByte[i*16+j];
  128.         mainLoop(num);
  129.     }
  130.     return changeHex(atemp).append(changeHex(btemp)).append(changeHex(ctemp)).append(changeHex(dtemp));
  131. }
  132. unsigned int main()
  133. {
  134.     string ss;
  135. //    cin>>ss;
  136.     string s=getMD5("abc");
  137.     cout<<s;
  138.     return 0;
  139. }</i></i></i></i>
复制代码



Yoki 「初入古黑」 2016-11-22 16:39 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

本帖最后由 Yoki 于 2016-11-22 16:50 编辑

Q:我没明白  md5既然是不可逆的  不就意味着是多对一的关系  那么如何计算出唯一的正确的密码 ?
A:我明白了,所谓的黑客的破解方法就是暴力破解法并不是真正解密,解密的正确率也不会达到100%.
Yoki 「初入古黑」 2016-11-22 18:40 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

Yoki 发表于 2016-11-22 16:39
Q:我没明白  md5既然是不可逆的  不就意味着是多对一的关系  那么如何计算出唯一的正确的密码 ?
A:我明 ...

傻啵....绕过验证的那种一般是对软件的暴力破解,和密码没关系啦。这里的暴力破解就是指你说的第一种,通过建立庞大的字典库对其中信息进行md5编码再与需要破译的东西比对,挨个遍历,最终得到真正的密码。
Yoki 「初入古黑」 2016-11-22 22:31 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

小执念 发表于 2016-11-22 22:27
你说的是哪一环节的密码计算?

md5你这里没有讲确切的环节啊...但下面程序里有转换的过程。总之我懂啦~就是不可逆的,伪“可解”的
Yoki 「初入古黑」 2016-11-23 21:07 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

补充下凯撒密码:就是所谓的以为的移位密码,相传是凯撒在行军打仗时发明出来的用来对军情密报进行加密以防止敌军截获后或的重要机密的一种措施,一般组成成分只有26个字母,会对其中的每一个字母都移动相同的位数来得到最终的密信。比如:qhaw vwdjh lv pdwkhpdwlf.sks(已经这是一个有关网页的信息,你能进行解密么?)
Yoki 「初入古黑」 2016-11-26 08:14 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

小执念 发表于 2016-11-23 23:15
写了个程序来解密,还没写完

(๑• . •๑)本来想写个md5的编码,结果发现好麻烦  参数好多 就搁置了
Yoki 「初入古黑」 2016-11-26 08:24 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

补充下base64:base64常用于在http下传输较长的标识信息,组成密码的可能性共有26*2+10+1+1+1,也就是大小写字母、数字、+、/与=这65种可能性,具有不可读性,也就是不能直接被人眼所理解,具体编码方法就是把64个字符原本的编码拆散重组得到新的编码后的字符串~感觉base64不太像是加密更像是字符转换,因为很容易揭秘~
暮色里的白雪檐 「出类拔萃」 2017-9-17 14:06 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

只能够这样用十五字来混混经验了
浅笑歌 「出类拔萃」 2018-5-6 21:23 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

睡于棺。#y435:
降临1994 「出类拔萃」 2018-5-6 22:04 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

有空一起交流一下
您需要登录后才可以回帖 登录 | 免费注册  

本版积分规则

关于本站|大事记|小黑屋|古黑论 网站统计

GMT+8, 2020-10-24 10:51 , Processed in 0.028544 second(s), 19 queries , Redis On.

© 2015-2020 GuHei.Net

Powered by Discuz! X3.4

快速回复 返回列表