歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> md5加密C語言實現

md5加密C語言實現

日期:2017/3/1 10:16:03   编辑:Linux編程

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