文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C语言实现MD5加密,竟如此简单!

2024-12-03 10:44

关注

一、摘要算法

摘要算法又称哈希算法。

它表示输入任意长度的数据,输出固定长度的数据,它的主要特征是加密过程不需要密钥,并且经过加密的数据无法被解密。

目前可以被解密逆向的只有CRC32算法,只有输入相同的明文数据经过相同的消息摘要算法才能得到相同的密文。

消息摘要算法不存在密钥的管理与分发问题,适合于分布式网络上使用。由于其加密计算的工作量相当巨大,所以以前的这种算法通常只用于数据量有限的情况下的加密。

消息摘要算法分为三类:

这三类算法的主要作用:验证数据的完整性

二、MD5简介

MD5即Message-Digest Algorithm 5(信息-摘要算法)。

属于摘要算法,是一个不可逆过程,就是无论多大数据,经过算法运算后都是生成固定长度的数据,结果使用16进制进行显示的128bit的二进制串。通常表示为32个十六进制数连成的字符串。

MD5有什么用?

用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。更多用在文档校验上,用来生成密钥检测文档是否被篡改。

三、在线MD5加密

有很多在线进行MD5加密的网站,如下:

http://www.metools.info/code/c26.html

举例: 给字符串 12334567 加密成。

 

如图结果为:

  1. 32135A337F8DC8E2BB9A9B80D86BDFD0 

四、C语言实现MD5算法

源文件如下:md5.h

  1. #ifndef MD5_H 
  2. #define MD5_H 
  3.   
  4. typedef struct 
  5.     unsigned int count[2]; 
  6.     unsigned int state[4]; 
  7.     unsigned char buffer[64];    
  8. }MD5_CTX; 
  9.   
  10.                           
  11. #define F(x,y,z) ((x & y) | (~x & z)) 
  12. #define G(x,y,z) ((x & z) | (y & ~z)) 
  13. #define H(x,y,z) (x^y^z) 
  14. #define I(x,y,z) (y ^ (x | ~z)) 
  15. #define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n))) 
  16. #define FF(a,b,c,d,x,s,ac) \ 
  17.           { \ 
  18.           a += F(b,c,d) + x + ac; \ 
  19.           a = ROTATE_LEFT(a,s); \ 
  20.           a += b; \ 
  21.           } 
  22. #define GG(a,b,c,d,x,s,ac) \ 
  23.           { \ 
  24.           a += G(b,c,d) + x + ac; \ 
  25.           a = ROTATE_LEFT(a,s); \ 
  26.           a += b; \ 
  27.           } 
  28. #define HH(a,b,c,d,x,s,ac) \ 
  29.           { \ 
  30.           a += H(b,c,d) + x + ac; \ 
  31.           a = ROTATE_LEFT(a,s); \ 
  32.           a += b; \ 
  33.           } 
  34. #define II(a,b,c,d,x,s,ac) \ 
  35.           { \ 
  36.           a += I(b,c,d) + x + ac; \ 
  37.           a = ROTATE_LEFT(a,s); \ 
  38.           a += b; \ 
  39.           }                                             
  40. void MD5Init(MD5_CTX *context); 
  41. void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen); 
  42. void MD5Final(MD5_CTX *context,unsigned char digest[16]); 
  43. void MD5Transform(unsigned int state[4],unsigned char block[64]); 
  44. void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len); 
  45. void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len); 
  46.   
  47. #endif 

md5.c

  1. #include  
  2. #include "md5.h" 
  3.   
  4. unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
  5.                          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
  6.                          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
  7.                          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 
  8.                           
  9. void MD5Init(MD5_CTX *context) 
  10.      context->count[0] = 0; 
  11.      context->count[1] = 0; 
  12.      context->state[0] = 0x67452301; 
  13.      context->state[1] = 0xEFCDAB89; 
  14.      context->state[2] = 0x98BADCFE; 
  15.      context->state[3] = 0x10325476; 
  16. void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen) 
  17.     unsigned int i = 0,index = 0,partlen = 0; 
  18.     index = (context->count[0] >> 3) & 0x3F; 
  19.     partlen = 64 - index
  20.     context->count[0] += inputlen << 3; 
  21.     if(context->count[0] < (inputlen << 3)) 
  22.        context->count[1]++; 
  23.     context->count[1] += inputlen >> 29; 
  24.      
  25.     if(inputlen >= partlen) 
  26.     { 
  27.        memcpy(&context->buffer[index],input,partlen); 
  28.        MD5Transform(context->state,context->buffer); 
  29.        for(i = partlen;i+64 <= inputlen;i+=64) 
  30.            MD5Transform(context->state,&input[i]); 
  31.        index = 0;         
  32.     }   
  33.     else 
  34.     { 
  35.         i = 0; 
  36.     } 
  37.     memcpy(&context->buffer[index],&input[i],inputlen-i); 
  38. void MD5Final(MD5_CTX *context,unsigned char digest[16]) 
  39.     unsigned int index = 0,padlen = 0; 
  40.     unsigned char bits[8]; 
  41.     index = (context->count[0] >> 3) & 0x3F; 
  42.     padlen = (index < 56)?(56-index):(120-index); 
  43.     MD5Encode(bits,context->count,8); 
  44.     MD5Update(context,PADDING,padlen); 
  45.     MD5Update(context,bits,8); 
  46.     MD5Encode(digest,context->state,16); 
  47. void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len) 
  48.     unsigned int i = 0,j = 0; 
  49.     while(j < len) 
  50.     { 
  51.          output[j] = input[i] & 0xFF;   
  52.          output[j+1] = (input[i] >> 8) & 0xFF; 
  53.          output[j+2] = (input[i] >> 16) & 0xFF; 
  54.          output[j+3] = (input[i] >> 24) & 0xFF; 
  55.          i++; 
  56.          j+=4; 
  57.     } 
  58. void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len) 
  59.      unsigned int i = 0,j = 0; 
  60.      while(j < len) 
  61.      { 
  62.            output[i] = (input[j]) | 
  63.                        (input[j+1] << 8) | 
  64.                        (input[j+2] << 16) | 
  65.                        (input[j+3] << 24); 
  66.            i++; 
  67.            j+=4;  
  68.      } 
  69. void MD5Transform(unsigned int state[4],unsigned char block[64]) 
  70.      unsigned int a = state[0]; 
  71.      unsigned int b = state[1]; 
  72.      unsigned int c = state[2]; 
  73.      unsigned int d = state[3]; 
  74.      unsigned int x[64]; 
  75.      MD5Decode(x,block,64); 
  76.      FF(a, b, c, d, x[ 0], 7, 0xd76aa478);  
  77.  FF(d, a, b, c, x[ 1], 12, 0xe8c7b756);  
  78.  FF(c, d, a, b, x[ 2], 17, 0x242070db);  
  79.  FF(b, c, d, a, x[ 3], 22, 0xc1bdceee);  
  80.  FF(a, b, c, d, x[ 4], 7, 0xf57c0faf);  
  81.  FF(d, a, b, c, x[ 5], 12, 0x4787c62a);  
  82.  FF(c, d, a, b, x[ 6], 17, 0xa8304613);  
  83.  FF(b, c, d, a, x[ 7], 22, 0xfd469501);  
  84.  FF(a, b, c, d, x[ 8], 7, 0x698098d8);  
  85.  FF(d, a, b, c, x[ 9], 12, 0x8b44f7af);  
  86.  FF(c, d, a, b, x[10], 17, 0xffff5bb1);  
  87.  FF(b, c, d, a, x[11], 22, 0x895cd7be);  
  88.  FF(a, b, c, d, x[12], 7, 0x6b901122);  
  89.  FF(d, a, b, c, x[13], 12, 0xfd987193);  
  90.  FF(c, d, a, b, x[14], 17, 0xa679438e);  
  91.  FF(b, c, d, a, x[15], 22, 0x49b40821);  
  92.   
  93.   
  94.  GG(a, b, c, d, x[ 1], 5, 0xf61e2562);  
  95.  GG(d, a, b, c, x[ 6], 9, 0xc040b340);  
  96.  GG(c, d, a, b, x[11], 14, 0x265e5a51);  
  97.  GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa);  
  98.  GG(a, b, c, d, x[ 5], 5, 0xd62f105d);  
  99.  GG(d, a, b, c, x[10], 9,  0x2441453);  
  100.  GG(c, d, a, b, x[15], 14, 0xd8a1e681);  
  101.  GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8);  
  102.  GG(a, b, c, d, x[ 9], 5, 0x21e1cde6);  
  103.  GG(d, a, b, c, x[14], 9, 0xc33707d6);  
  104.  GG(c, d, a, b, x[ 3], 14, 0xf4d50d87);  
  105.  GG(b, c, d, a, x[ 8], 20, 0x455a14ed);  
  106.  GG(a, b, c, d, x[13], 5, 0xa9e3e905);  
  107.  GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8);  
  108.  GG(c, d, a, b, x[ 7], 14, 0x676f02d9);  
  109.  GG(b, c, d, a, x[12], 20, 0x8d2a4c8a);  
  110.   
  111.   
  112.  HH(a, b, c, d, x[ 5], 4, 0xfffa3942);  
  113.  HH(d, a, b, c, x[ 8], 11, 0x8771f681);  
  114.  HH(c, d, a, b, x[11], 16, 0x6d9d6122);  
  115.  HH(b, c, d, a, x[14], 23, 0xfde5380c);  
  116.  HH(a, b, c, d, x[ 1], 4, 0xa4beea44);  
  117.  HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9);  
  118.  HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60);  
  119.  HH(b, c, d, a, x[10], 23, 0xbebfbc70);  
  120.  HH(a, b, c, d, x[13], 4, 0x289b7ec6);  
  121.  HH(d, a, b, c, x[ 0], 11, 0xeaa127fa);  
  122.  HH(c, d, a, b, x[ 3], 16, 0xd4ef3085);  
  123.  HH(b, c, d, a, x[ 6], 23,  0x4881d05);  
  124.  HH(a, b, c, d, x[ 9], 4, 0xd9d4d039);  
  125.  HH(d, a, b, c, x[12], 11, 0xe6db99e5);  
  126.  HH(c, d, a, b, x[15], 16, 0x1fa27cf8);  
  127.  HH(b, c, d, a, x[ 2], 23, 0xc4ac5665);  
  128.   
  129.   
  130.  II(a, b, c, d, x[ 0], 6, 0xf4292244);  
  131.  II(d, a, b, c, x[ 7], 10, 0x432aff97);  
  132.  II(c, d, a, b, x[14], 15, 0xab9423a7);  
  133.  II(b, c, d, a, x[ 5], 21, 0xfc93a039);  
  134.  II(a, b, c, d, x[12], 6, 0x655b59c3);  
  135.  II(d, a, b, c, x[ 3], 10, 0x8f0ccc92);  
  136.  II(c, d, a, b, x[10], 15, 0xffeff47d);  
  137.  II(b, c, d, a, x[ 1], 21, 0x85845dd1);  
  138.  II(a, b, c, d, x[ 8], 6, 0x6fa87e4f);  
  139.  II(d, a, b, c, x[15], 10, 0xfe2ce6e0);  
  140.  II(c, d, a, b, x[ 6], 15, 0xa3014314);  
  141.  II(b, c, d, a, x[13], 21, 0x4e0811a1);  
  142.  II(a, b, c, d, x[ 4], 6, 0xf7537e82);  
  143.  II(d, a, b, c, x[11], 10, 0xbd3af235);  
  144.  II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb);  
  145.  II(b, c, d, a, x[ 9], 21, 0xeb86d391);  
  146.      state[0] += a; 
  147.      state[1] += b; 
  148.      state[2] += c; 
  149.      state[3] += d; 

五、MD5加密实例

MD5加密步骤如下:

定义

  1. MD5_CTX md5c;  

初始化

  1.  
  2. MD5Init(MD5_CTX *context); 

MD5值计算

实现MD5值的计算及结构体的更新:

  1.  
  2. MD5Update(MD5_CTX *context,(unsigned char *)input,inputLen);  

输出转换

  1.  
  2. MD5Final(MD5_CTX *context,unsigned char digest[16]); 

格式整理

转换成32位的16进制字符串。

实例1 字符串加密

对字符串进行加密:

  1.  1 #include  
  2.  2 #include  
  3.  3 #include "md5.h" 
  4.  4 #include  
  5.  5 #include  
  6.  6 #include  
  7.  7 #include  
  8.  8  
  9.  9 void main( void )  
  10. 10 {  
  11. 11     int read_len; 
  12. 12     int i ; 
  13. 13     char temp[8]={0}; 
  14. 14     unsigned char digest[16]; //存放结果  
  15. 15     char hexbuf[128]="12334567"
  16. 16     unsigned char decrypt[16]={0};   
  17. 17     unsigned char decrypt32[64]={0};     
  18. 18  
  19. 19     MD5_CTX md5c;  
  20. 20  
  21. 21     MD5Init(&md5c); //初始化 
  22. 22     read_len = strlen(hexbuf); 
  23. 23     MD5Update(&md5c,(unsigned char *)hexbuf,read_len);   
  24. 24  
  25. 25     MD5Final(&md5c,decrypt);  
  26. 26     strcpy((char *)decrypt32,""); 
  27. 27  
  28. 28     for(i=0;i<16;i++) 
  29. 29     { 
  30. 30         sprintf(temp,"%02x",decrypt[i]); 
  31. 31         strcat((char *)decrypt32,temp); 
  32. 32     } 
  33. 33     printf("md5:%s\n",decrypt32); 
  34. 34      
  35. 35     return
  36. 36 } 

执行结果如下:

 

本例对字符串12334567进行加密,结果和在线加密结果一致。

实例2 文件加密

对文件进行加密

  1. #include  
  2. #include  
  3. #include "md5.h" 
  4. #include  
  5. #include  
  6. #include  
  7. #include  
  8.  
  9. #define FORWORD_fw "123.c" 
  10.  
  11. int calc_md5(char*filename,char*dest) 
  12.  int i; 
  13.  int filelen = 0; 
  14.  int read_len; 
  15.  char temp[8]={0};  
  16.  char hexbuf[128]={0}; 
  17.  unsigned char decrypt[16]={0};   
  18.  unsigned char decrypt32[64]={0}; 
  19.  MD5_CTX md5; 
  20.  char fw_path[128]; 
  21.  
  22.  int fdf; 
  23.   
  24.  fdf = open(filename,O_RDWR); 
  25.  if(fdf<0) 
  26.  { 
  27.   printf("%s not exist\n",FORWORD_fw); 
  28.   return -1; 
  29.  } 
  30.   
  31.  MD5Init(&md5);   
  32.  while(1) 
  33.  { 
  34.   read_len = read(fdf, hexbuf,sizeof(hexbuf));  
  35.   if (read_len <0) {   
  36.    close(fdf);    
  37.    return -1; 
  38.   } 
  39.   if(read_len==0) 
  40.   { 
  41.    break; 
  42.   } 
  43.   filelen += read_len; 
  44.   MD5Update(&md5,(unsigned char *)hexbuf,read_len);  
  45.  } 
  46.  
  47.   
  48.  MD5Final(&md5,decrypt);  
  49.  strcpy((char *)decrypt32,""); 
  50.   
  51.  for(i=0;i<16;i++) 
  52.  { 
  53.   sprintf(temp,"%02x",decrypt[i]); 
  54.   strcat((char *)decrypt32,temp); 
  55.  } 
  56.  strcpy(dest,decrypt32); 
  57.  
  58.  printf("md5:%s len=%d\n",dest,filelen); 
  59.  close(fdf); 
  60.  
  61.  return filelen; 
  62. int main(int argc, char *argv[]) 
  63.  int ret; 
  64.  int filelen; 
  65.  char md5_str[64]={0}; 
  66.  char cmd[256]={0}; 
  67.   
  68.  filelen = calc_md5(FORWORD_fw,md5_str); 
  69.  if(filelen<0) 
  70.  { 
  71.   printf("calc_md5 fail\n"); 
  72.   return -1; 
  73.  } 
  74.  
  75.  return 0; 

运行结果:

 

在线验证结果对比:

http://www.metools.info/other/o21.html

结果

本文转载自微信公众号「一口Linux」,可以通过以下二维码关注。转载本文请联系一口Linux公众号。

 

来源:一口Linux内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯