md5加密C语言实现


md5加密,这里的程序只是简单实现了md5加密的效果,适用于字符串,

md5加密的主要步骤为:

1.md5结构体定义,即md5头文件。

  1. #ifndef MD5_FORENCRPTY_H   
  2. #define MD5_FORENCRPTY_H   
  3. /*this is only 32bit*/  
  4. typedef unsigned int md5_int;  
  5. struct MD5_struct  
  6. {  
  7.     md5_int A;  
  8.     md5_int B;  
  9.     md5_int C;  
  10.     md5_int D;  
  11.     md5_int lenbuf;      
  12.     char buffer[128];  
  13. };  
  14. void md5_init(struct MD5_struct *ctx,char * buffer);  
  15. void md5_process(struct MD5_struct * ctx);  
  16. char * md5_fini(struct MD5_struct *ctx,void *rebuf);  
  17. void md5_buffer_full(struct MD5_struct * ctx);  
  18. void md5_print(struct MD5_struct * ctx);  
  19. #endif  

2.信息初始化。

md5以512位分组来处理输入文本,每一分组又划分为16个32位子分组。
首先填充消息使其长度恰好为一个比512位的倍数仅小64位的数。填充方法是附一个1在消息后面,后接所要求的多个0,然后在其后附上64位的消息(信息)长度。

需要用于用于初始化md5结构体的四个32位变量为:

  1. ctx->A=0x67452301;  
  2. ctx->B=0xefcdab89;  
  3. ctx->C=0x98badcfe;  
  4. ctx->D=0x10325476;  

3.定义循环的线性函数。

  1. #define F(x,y,z) (((x)&(y))|((~x)&(z)))   
  2. #define G(x,y,z) (((x)&(z))|((y)&(~z)))   
  3. #define H(x,y,z) ((x)^(y)^(z))   
  4. #define I(x,y,z) ((y)^((x)|(~z)))   
  5. //数据移位处理   
  6. #define ROT(x,s) (x=(x<<s)|(x>>(32-s)))   
  7. #define FF(a,b,c,d,j,s,T) {a=a+(F(b,c,d)+M[j]+T);ROT(a,s);a=a+b;}   
  8. #define GG(a,b,c,d,j,s,T) {a=a+(G(b,c,d)+M[j]+T);ROT(a,s);a=a+b;}   
  9. #define HH(a,b,c,d,j,s,T) {a=a+(H(b,c,d)+M[j]+T);ROT(a,s);a=a+b;}   
  10. #define II(a,b,c,d,j,s,T) {a=a+(I(b,c,d)+M[j]+T);ROT(a,s);a=a+b;}   
  11. //Mj表示消息的第j个子分组(从0到15)  

4.循环处理信息

循环的次数是消息中512位消息分组的数目。
主循环有四轮,每轮很相拟。第一轮进行16次操作。每次操作对a,b,c和d中的其中三个作一次非线性函数运算,然后将所得结果加上第四个变量,文本的一个子分组和一个常数。
再将所得结果向右环移一个不定的数,并加上a,b,c或d中之一。最后用该结果取代a,b,c或d中之一。
所有这些完成之后,将A,B,C,D分别加上a,b,c,d。然后用下一分组数据继续运行算法,具体的算法定义见步骤2。
5.md5加密数据输出。
算法的输出由四个32位分组组成,将它们形成一个128位散列值,即A,B,C,D组成。

md5.c

  1. /* 
  2.  md5.c 
  3.  this is for encryt by md5,just simple implement it. 
  4. */  
  5.   
  6. #include <stdio.h>   
  7. #include <string.h>   
  8. #include "md5.h"   
  9.   
  10. struct MD5_struct ctx;  
  11.   
  12. extern void md5_init(struct MD5_struct *ctx,char * buffer);  
  13. extern void md5_process(struct MD5_struct * ctx);  
  14. extern char * md5_fini(struct MD5_struct *ctx,void * rebuf);  
  15. extern void md5_buffer_full(struct MD5_struct * ctx);  
  16. extern void md5_print(struct MD5_struct * ctx);  
  17.   
  18. /* set data for fill buffer */  
  19. md5_int fullbuffer[64]={0x80,0};  
  20. md5_int M[16]={0,0};  
  21.   
  22. /* 
  23.  for loop A\B\C\D ways 
  24. */  
  25. #define F(x,y,z) (((x)&(y))|((~x)&(z)))   
  26. #define G(x,y,z) (((x)&(z))|((y)&(~z)))   
  27. #define H(x,y,z) ((x)^(y)^(z))   
  28. #define I(x,y,z) ((y)^((x)|(~z)))   
  29.   
  30. #define ROT(x,s) (x=(x<<s)|(x>>(32-s)))   
  31.   
  32. #define FF(a,b,c,d,j,s,T) {a=a+(F(b,c,d)+M[j]+T);ROT(a,s);a=a+b;}   
  33. #define GG(a,b,c,d,j,s,T) {a=a+(G(b,c,d)+M[j]+T);ROT(a,s);a=a+b;}   
  34. #define HH(a,b,c,d,j,s,T) {a=a+(H(b,c,d)+M[j]+T);ROT(a,s);a=a+b;}   
  35. #define II(a,b,c,d,j,s,T) {a=a+(I(b,c,d)+M[j]+T);ROT(a,s);a=a+b;}   
  36.   
  37. /* 
  38.  init MD5_struct ctx 
  39. */  
  40. void md5_init(struct MD5_struct *ctx,char * buffer)  
  41. {  
  42.     ctx->A=0x67452301;  
  43.     ctx->B=0xefcdab89;  
  44.     ctx->C=0x98badcfe;  
  45.     ctx->D=0x10325476;  
  46.     ctx->lenbuf=strlen(buffer);  
  47.     memcpy(ctx->buffer,buffer,ctx->lenbuf);  
  48. }  
  49.   
  50. /* 
  51.  print ctx's message  
  52. */  
  53. void md5_print(struct MD5_struct *ctx)  
  54. {  
  55.     printf("******************************\n");  
  56.     printf("ctx->A:%x\n",ctx->A);  
  57.     printf("ctx->B:%x\n",ctx->B);  
  58.     printf("ctx->C:%x\n",ctx->C);  
  59.     printf("ctx->D:%x\n",ctx->D);  
  60.     printf("ctx->lenbuf:%d\n",ctx->lenbuf);  
  61.     printf("ctx->buffer:%s\n",ctx->buffer);  
  62.     printf("******************************\n");  
  63.   
  64. }  
  65.   
  66. /* 
  67.  fill buffer to mod%64 
  68. */  
  69. void md5_buffer_full(struct MD5_struct *ctx)  
  70. {  
  71.     md5_int sizebyte[2]={0,0};  
  72.     md5_int len=ctx->lenbuf;  
  73.     md5_int byte=len>56?(64-(len-56)):56-len;  
  74.     memcpy(&ctx->buffer[len],fullbuffer,byte);  
  75.     sizebyte[0]+=(ctx->lenbuf<<3);  
  76.     if(sizebyte[0]<ctx->lenbuf)  
  77.         sizebyte[1]++;  
  78.   
  79.     memcpy(&ctx->buffer[len+byte],&sizebyte,sizeof(sizebyte));     
  80.       
  81. }  
  82. /* 
  83.  deal message 
  84. */  
  85. void md5_process(struct MD5_struct *ctx)  
  86. {  
  87.     int i=0;  
  88.     int j;  
  89.     md5_int a=ctx->A;  
  90.     md5_int b=ctx->B;  
  91.     md5_int c=ctx->C;  
  92.     md5_int d=ctx->D;  
  93.     for(i=0;i<=ctx->lenbuf;i+=64)//loop time   
  94.     {  
  95.         memcpy(M,ctx->buffer,sizeof(md5_int)*16);  
  96.   
  97.         /* round 1 */  
  98.         FF(a,b,c,d, 0, 7,0xd76aa478);   
  99.         FF(d,a,b,c, 1,12,0xe8c7b756);   
  100.         FF(c,d,a,b, 2,17,0x242070db);  
  101.         FF(b,c,d,a, 3,22,0xc1bdceee);   
  102.         FF(a,b,c,d, 4, 7,0xf57c0faf);   
  103.         FF(d,a,b,c, 5,12,0x4787c62a);   
  104.         FF(c,d,a,b, 6,17,0xa8304613);   
  105.         FF(b,c,d,a, 7,22,0xfd469501);   
  106.         FF(a,b,c,d, 8, 7,0x698098d8);   
  107.         FF(d,a,b,c, 9,12,0x8b44f7af);   
  108.         FF(c,d,a,b,10,17,0xffff5bb1);   
  109.         FF(b,c,d,a,11,22,0x895cd7be);  
  110.         FF(a,b,c,d,12, 7,0x6b901122);   
  111.         FF(d,a,b,c,13,12,0xfd987193);   
  112.         FF(c,d,a,b,14,17,0xa679438e);   
  113.         FF(b,c,d,a,15,22,0x49b40821);  
  114.   
  115.         /* round 2 */  
  116.         GG(a,b,c,d, 1, 5,0xf61e2562);  
  117.         GG(d,a,b,c, 6, 9,0xc040b340);  
  118.         GG(c,d,a,b,11,14,0x265e5a51);   
  119.         GG(b,c,d,a, 0,20,0xe9b6c7aa);   
  120.         GG(a,b,c,d, 5, 5,0xd62f105d);   
  121.         GG(d,a,b,c,10, 9,0x02441453);   
  122.         GG(c,d,a,b,15,14,0xd8a1e681);   
  123.         GG(b,c,d,a, 4,20,0xe7d3fbc8);   
  124.         GG(a,b,c,d, 9, 5,0x21e1cde6);   
  125.         GG(d,a,b,c,14, 9,0xc33707d6);   
  126.         GG(c,d,a,b, 3,14,0xf4d50d87);   
  127.         GG(b,c,d,a, 8,20,0x455a14ed);   
  128.         GG(a,b,c,d,13, 5,0xa9e3e905);     
  129.         GG(d,a,b,c, 2, 9,0xfcefa3f8);   
  130.         GG(c,d,a,b, 7,14,0x676f02d9);   
  131.         GG(b,c,d,a,12,20,0x8d2a4c8a);  
  132.   
  133.         /* round 3 */  
  134.         HH(a,b,c,d, 5, 4,0xfffa3942);   
  135.         HH(d,a,b,c, 8,11,0x8771f681);   
  136.         HH(c,d,a,b,11,16,0x6d9d6122);   
  137.         HH(b,c,d,a,14,23,0xfde5380c);   
  138.         HH(a,b,c,d, 1, 4,0xa4beea44);   
  139.         HH(d,a,b,c, 4,11,0x4bdecfa9);   
  140.         HH(c,d,a,b, 7,16,0xf6bb4b60);   
  141.         HH(b,c,d,a,10,23,0xbebfbc70);   
  142.         HH(a,b,c,d,13, 4,0x289b7ec6);   
  143.         HH(d,a,b,c, 0,11,0xeaa127fa);   
  144.         HH(c,d,a,b, 3,16,0xd4ef3085);   
  145.         HH(b,c,d,a, 6,23,0x04881d05);   
  146.         HH(a,b,c,d, 9, 4,0xd9d4d039);   
  147.         HH(d,a,b,c,12,11,0xe6db99e5);  
  148.         HH(c,d,a,b,15,16,0x1fa27cf8);   
  149.         HH(b,c,d,a, 2,23,0xc4ac5665);  
  150.   
  151.         /* round 4 */  
  152.         II(a,b,c,d, 0, 6,0xf4292244);   
  153.         II(d,a,b,c, 7,10,0x432aff97);   
  154.         II(c,d,a,b,14,15,0xab9423a7);   
  155.         II(b,c,d,a, 5,21,0xfc93a039);   
  156.         II(a,b,c,d,12, 6,0x655b59c3);   
  157.         II(d,a,b,c, 3,10,0x8f0ccc92);   
  158.         II(c,d,a,b,10,15,0xffeff47d);   
  159.         II(b,c,d,a, 1,21,0x85845dd1);   
  160.         II(a,b,c,d, 8, 6,0x6fa87e4f);   
  161.         II(d,a,b,c,15,10,0xfe2ce6e0);   
  162.         II(c,d,a,b, 6,15,0xa3014314);   
  163.         II(b,c,d,a,13,21,0x4e0811a1);   
  164.         II(a,b,c,d, 4, 6,0xf7537e82);   
  165.         II(d,a,b,c,11,10,0xbd3af235);   
  166.         II(c,d,a,b, 2,15,0x2ad7d2bb);   
  167.         II(b,c,d,a, 9,21,0xeb86d391);  
  168.   
  169.         ctx->A+=a;  
  170.         ctx->B+=b;  
  171.         ctx->C+=c;  
  172.         ctx->D+=d;  
  173.   
  174.     }  
  175.   
  176. }  
  177.   
  178. /* 
  179.  store result 
  180. */  
  181. char * md5_fini(struct MD5_struct *ctx,void *rebuf)  
  182. {  
  183.     int i=0;  
  184.     memset(rebuf,0,16);  
  185.     memcpy(&((unsigned char *)rebuf)[0],&ctx->A,sizeof(ctx->A));  
  186.     memcpy(&((unsigned char *)rebuf)[4],&ctx->B,sizeof(ctx->B));  
  187.     memcpy(&((unsigned char *)rebuf)[8],&ctx->C,sizeof(ctx->C));  
  188.     memcpy(&((unsigned char *)rebuf)[12],&ctx->D,sizeof(ctx->D));  
  189.     /* print md5 result */  
  190.     md5_print(ctx);  
  191.     printf("md5:");  
  192.     while(i<16)  
  193.     {  
  194.         printf("%02x",((unsigned char *)rebuf)[i++]);  
  195.     }  
  196.         printf("\n*********************************\n");  
  197.     return rebuf;  
  198. }  
  199. int main(int argc,char ** argv)  
  200. {  
  201.     unsigned char rebuf[16];  
  202.     unsigned char message[64];  
  203.     printf("please enter you message for encrypt:");  
  204.     scanf("%s",message);  
  205.     md5_init(&ctx,message);  
  206.     md5_buffer_full(&ctx);  
  207.     md5_process(&ctx);  
  208.     md5_fini(&ctx,rebuf);  
  209.     return 0;  
  210. }  

相关内容