md5加密算法描述:MD5算法的C#程序 MD5算法描述

  当我要写个MD5算法发现中英文语言描述都有些不确切地方某些个细节

  讲得不清楚或者说很费解最后不得不拿出C语言来调试这对于理解算法是很不

  利于是就整理总结了下我摸索到些要点

  1.来历

  MD5全称是message-digest algorithm 5(信息-摘要算法在90年代初由mit laboratory

  for computer science和rsa data security incronald l. rivest开发出来

  经md2、md3和md4发展而来 http://www.ietf.org/rfc/rfc1321.txt 份最权威文档

  由ronald l. rivest在1992年8月向ieft提交

  2.用途

  MD5作用是对段信息(message)生成信息摘要(message-digest)该摘要对该信息具有

  唯性,可以作为数字签名用于验证文件有效性(是否有丢失或损坏数据),对用户

  密码加密在哈希中计算散列值

  3.特点

  输入个任意长度字节串生成个128位整数由于算法某些不可逆特征在加密应用

  上有较好安全性并且MD5算法使用不需要支付任何版权费用

  4.介绍说明

  唯性和不可逆性都不是绝对从理论上分析是种多对关系但两个区别信息产生

  相同摘要概率很小不可逆是指从输出反推输入所需运算量和计算时间太大使用穷搜字

  典思路方法又需要太多存储空间

  5.算法描述

  算法输入是个字节串每个字节是8个bit.

  算法执行分为以下几个步骤:

  第补位:

  MD5算法先对输入数据进行补位使得数据长度(以为单位)对64求余结果是56

  即数据扩展至LEN=K*64+56个字节K为整数

  补位思路方法:补个1然后补0至满足上述要求相当于补个0x80字节再补值

  为0字节步里总共补充字节数为0~63个

  第 2步附加数据长度:

  用个64位整数表示数据原始长度(以bit为单位)将这个数字8个字节按低位在前

  高位在后顺序附加在补位后数据后面这时数据被填补后总长度为:

  LEN = K*64+56+8=(K+1)*64 Bytes

  ※注意那个64位整数是输入数据原始长度而不是填充字节后长度,我就在这里栽了跟头.

  第 3步化MD5参数:

  有 4个32位整数变量 (A,B,C,D) 用来计算信息摘要个变量被化成以下

  以十 6进制数表示数值低位字节在前面

word A: 01 23 45 67
word B: 89 ab cd ef
word C: fe dc ba 98
word D: 76 54 32 10
※注意低位字节在前面指是Little Endian平台上内存中字节排列方式

  而在中书写时要写成:

  A=0x67452301
B=0xefcdab89
C=0x98badcfe
D=0x10325476
  第 4步定义 4个MD5基本按位操作:

  XYZ为32位整数

F(X,Y,Z) = (X and Y) or (not(X) and Z)
G(X,Y,Z) = (X and Z) or (Y and not(Z))
H(X,Y,Z) = X xor Y xor Z
I(X,Y,Z) = Y xor (X or not(Z))
  再定义 4个分别用于 4轮变换

  设Mj表示消息第j个子分组(从0到15)<<FF(a,b,c,d,Mj,s,ti)表示a=b+((a+(F(b,c,d)+Mj+ti)<<GG(a,b,c,d,Mj,s,ti)表示a=b+((a+(G(b,c,d)+Mj+ti)<<HH(a,b,c,d,Mj,s,ti)表示a=b+((a+(H(b,c,d)+Mj+ti)<<II(a,b,c,d,Mj,s,ti)表示a=b+((a+(I(b,c,d)+Mj+ti)<<第 5步对输入数据作变换

  处理数据N是总字节数以64个字节为每组作次循环每次循环进行 4轮操作

  要变换64个字节用16个32位整数M[0 ...15]表示T[1 ... 64]表示组常数

  T[i]为4294967296*abs(sin(i))32位整数部分i单位是弧度,i取值从1到64

  具体过程如下:

  /* 设置主循环变量 */

For i = 0 to N/16-1 do  /*每循环把数据原文存放在16个元素X中. */

For j = 0 to 15 do
Set X[j] to M[i*16+j].
end /结束对J循环
/* Save A as AA, B as BB, C as CC, and D as DD.
*/
AA = A
BB = B
CC = C
DD = D
/* 第1轮*/
/* 以 [abcd k s i]表示如下操作
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
[ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4]
[ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8]
[ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12]
[ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16]
/* 第2轮* */
/* 以 [abcd k s i]表示如下操作
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
[ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20]
[ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24]
[ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28]
[ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32]
/* 第3轮*/
/* 以 [abcd k s i]表示如下操作
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
[ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36]
[ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40]
[ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44]
[ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48]
/* 第4轮*/
/* 以 [abcd k s i]表示如下操作
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
/* Do the following 16 operations. */
[ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51] [BCDA 5 21 52]
[ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55] [BCDA 1 21 56]
[ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59] [BCDA 13 21 60]
[ABCD 4 6 61] [DABC 11 10 62] [CDAB 2 15 63] [BCDA 9 21 64]
/* 然后进行如下操作 */
A = A + AA
B = B + BB
C = C + CC
D = D + DD
  Next i /* 结束对I循环*/

  第 6步输出结果

  ABCD连续存放共16个字节128位按十 6进制依次输出这个16个字节

  最后语言实现算法后可以输入以下几个信息对个简单测试

  看看有没有

  MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
  MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
  MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
  MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
  MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
  MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =
d174ab98d277d9f5a5611c2c9f419d9f
MD5 ("123456789012345678901234567890123456789012345678901234567890123456789
01234567890") = 57edf4a22be3c955ac49da2e2107b67a
  MD5算法的C#

  MD5算法比较特别最适合用汇编语言来写好多高级语言对的无能无力或效率极低

  比如我最开始尝试用Python和Euphoria编写发现不太容易相比而言C#作为C家簇

  中新兴门.net语言功能比较全面花了晚上工夫终于用C#最先实现了MD5

  主要是由于对算法些细节不太注意结果输出总是不对调试了好长时间

//源文件:md5.cs
// MD5 Alogrithm
// by rufi 2004.6.20 http://rufi.yculblog.com/
using ;
using .Collections;
using .IO;
public MD5 {
// state variables
private UInt32 A;
private UInt32 B;
private UInt32 C;
private UInt32 D;
//number of bits to rotate in tranforming
private const S11 = 7;
private const S12 = 12;
private const S13 = 17;
private const S14 = 22;
private const S21 = 5;
private const S22 = 9;
private const S23 = 14;
private const S24 = 20;
private const S31 = 4;
private const S32 = 11;
private const S33 = 16;
private const S34 = 23;
private const S41 = 6;
private const S42 = 10;
private const S43 = 15;
private const S44 = 21;
/* F, G, H and I are basic MD5 functions.
* 4个非线性:
*
* F(X,Y,Z) =(X&Y)|((~X)&Z)
* G(X,Y,Z) =(X&Z)|(Y&(~Z))
* H(X,Y,Z) =X^Y^Z
* I(X,Y,Z)=Y^(X|(~Z))
*
* (&和|或~非^异或)
*/
private UInt32 F(UInt32 x,UInt32 y,UInt32 z){
(x&y)|((~x)&z);
}
private UInt32 G(UInt32 x,UInt32 y,UInt32 z){
(x&z)|(y&(~z));
}
private UInt32 H(UInt32 x,UInt32 y,UInt32 z){
x^y^z;
}
private UInt32 I(UInt32 x,UInt32 y,UInt32 z){
y^(x|(~z));
}
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
* Rotation is separate from addition to prevent recomputation.
*/
private void FF(ref UInt32 a,UInt32 b,UInt32 c,UInt32 d,UInt32 mj, s,UInt32 ti){
a = a + F(b,c,d) + mj + ti;
a = a << s | a >>(32-s);
a b;
}
private void GG(ref UInt32 a,UInt32 b,UInt32 c,UInt32 d,UInt32 mj, s,UInt32 ti){
a = a + G(b,c,d) + mj + ti;
a = a << s | a >>(32-s);
a b;
}
private void HH(ref UInt32 a,UInt32 b,UInt32 c,UInt32 d,UInt32 mj, s,UInt32 ti){
a = a + H(b,c,d) + mj + ti;
a = a << s | a >>(32-s);
a b;
}
private void II(ref UInt32 a,UInt32 b,UInt32 c,UInt32 d,UInt32 mj, s,UInt32 ti){
a = a + I(b,c,d) + mj + ti;
a = a << s | a >>(32-s);
a b;
}
private void MD5_Init{
A=0x67452301; //in memory, this is 0x01234567
B=0xefcdab89; //in memory, this is 0x89abcdef
C=0x98badcfe; //in memory, this is 0xfedcba98
D=0x10325476; //in memory, this is 0x76543210
}
private UInt32 MD5_Append( input){
zeros=0;
_disibledevent=Test("12345678901234567890123456789012345678901234567890123456789012345678901234567890");
s;
}
}


Tags:  md5加密算法 md5算法 md5加密算法c md5加密算法描述

延伸阅读

最新评论

发表评论