MD5 加密源码(C语言)
2016-06-28 00:00
423 查看
摘要: MD5 加密源码
#include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define N 1024 #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) #define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n)))) #define FF(a, b, c, d, x, s, ac) { (a) += F ((b), (c), (d)) + (x) + ac; (a) = ROL ((a), (s)); (a) += (b); } #define GG(a, b, c, d, x, s, ac) { (a) += G ((b), (c), (d)) + (x) + ac; (a) = ROL ((a), (s)); (a) += (b); } #define HH(a, b, c, d, x, s, ac) { (a) += H ((b), (c), (d)) + (x) + ac; (a) = ROL ((a), (s)); (a) += (b); } #define II(a, b, c, d, x, s, ac) { (a) += I ((b), (c), (d)) + (x) + ac; (a) = ROL ((a), (s)); (a) += (b); } typedef unsigned char UINT8; typedef unsigned int UINT32; UINT32 s[64] = { 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}, t[64] = { 0Xd76aa478, 0Xe8c7b756, 0X242070db, 0Xc1bdceee, 0Xf57c0faf, 0X4787c62a, 0Xa8304613, 0Xfd469501, 0X698098d8, 0X8b44f7af, 0Xffff5bb1, 0X895cd7be, 0X6b901122, 0Xfd987193, 0Xa679438e, 0X49b40821, 0Xf61e2562, 0Xc040b340, 0X265e5a51, 0Xe9b6c7aa, 0Xd62f105d, 0X2441453, 0Xd8a1e681, 0Xe7d3fbc8, 0X21e1cde6, 0Xc33707d6, 0Xf4d50d87, 0X455a14ed, 0Xa9e3e905, 0Xfcefa3f8, 0X676f02d9, 0X8d2a4c8a, 0Xfffa3942, 0X8771f681, 0X6d9d6122, 0Xfde5380c, 0Xa4beea44, 0X4bdecfa9, 0Xf6bb4b60, 0Xbebfbc70, 0X289b7ec6, 0Xeaa127fa, 0Xd4ef3085, 0x4881d05, 0Xd9d4d039, 0Xe6db99e5, 0X1fa27cf8, 0Xc4ac5665, 0Xf4292244, 0X432aff97, 0Xab9423a7, 0Xfc93a039, 0X655b59c3, 0X8f0ccc92, 0Xffeff47d, 0X85845dd1, 0X6fa87e4f, 0Xfe2ce6e0, 0Xa3014314, 0X4e0811a1, 0Xf7537e82, 0Xbd3af235, 0X2ad7d2bb, 0Xeb86d391}, Index[64] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12, 5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2, 0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9}, INIT[4] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476}; ////////////////////////////////////////// // 工具函数 // ////////////////////////////////////////// FILE *open(UINT8 *filename, UINT8 *mode) //打开文件 { FILE *fp = NULL; if((fp = fopen(filename, mode)) == NULL) { printf("file open error!\n"); exit(-1); } return fp; } void close(FILE *fp) //关闭文件 { while(fclose(fp)); } /*将整型数据转换成字符串数据*/ void encode(UINT32 *input, UINT8 *output, UINT32 len) { UINT32 i, j; for(i = 0, j = 0; i < len; i += 4, j++) { output[i] = (UINT8)(input[j] & 0Xff); output[i + 1] = (UINT8)((input[j] >> 8 ) & 0Xff); output[i + 2] = (UINT8)((input[j] >> 16) & 0Xff); output[i + 3] = (UINT8)((input[j] >> 24) & 0Xff); } } /*将字符串转换成整型数据*/ void decode(UINT8 * input, UINT32 * output, UINT32 len) { UINT32 i = 0, j = 0; for(; i < len; i += 4, j++) output[j] = (UINT32)input[i] | (((UINT32)input[i + 1])<<8) | (((UINT32)input[i + 2])<<16) | (((UINT32)input[i + 3])<<24); } ////////////////////////////////////////// // 功能函数 // ////////////////////////////////////////// /*初始化链块变量*/ void init_md5() { INIT[0] = 0x67452301; INIT[1] = 0xefcdab89; INIT[2] = 0x98badcfe; INIT[3] = 0x10325476; } /*数字签名计算*/ void digest_opt(UINT8 *m, UINT32 len) { UINT32 i = 0, j = 0, k = 0, temp[4], date[16]; for(i = 0; i < 4; i++) temp[i] = INIT[i]; /*对多个数据快进行签名运算*/ for(; len > 0; len -= 64, j += 4) { /*将64字节的字符串转换成16个整型数据*/ decode(m+j, date, 64); for(i = 0; i < 64; i++, k = (k+4-1)%4) { switch(i/16) { case 0: FF(temp[k%4], temp[(k+1)%4], temp[(k+2)%4], temp[(k+3)%4], date[Index[i]], s[i], t[i]); break; case 1: GG(temp[k%4], temp[(k+1)%4], temp[(k+2)%4], temp[ 7fe0 (k+3)%4], date[Index[i]], s[i], t[i]); break; case 2: HH(temp[k%4], temp[(k+1)%4], temp[(k+2)%4], temp[(k+3)%4], date[Index[i]], s[i], t[i]); break; case 3: II(temp[k%4], temp[(k+1)%4], temp[(k+2)%4], temp[(k+3)%4], date[Index[i]], s[i], t[i]); break; default: break; } } } for(i = 0; i < 4; i++) INIT[i] += temp[i]; } /*计算需要填充的字节长度*/ UINT32 pad_len(UINT32 len) { UINT32 mod; mod = len%64; /*p_len 为填充字节数计算*/ if(mod <= 56) len = 64 - mod; else len = 128 - mod; return len; } /*计算原消息长度的填充信息*/ void len_data(UINT8 * msgLen, const UINT32 len) { UINT32 bufLen[2]; /*计算数据长度的填充数据*/ bufLen[0] = len << 3; bufLen[1] = len >> 29; encode(bufLen, msgLen, 8); } /*字节填充*/ UINT8 * tail_pad(UINT8 * msg, UINT8 *msgLen, const UINT32 len, const UINT32 padLen) { UINT8 *buf = NULL; /*根据填充字节数构建新串*/ buf = (UINT8 *)calloc(sizeof(UINT8), len + padLen); /*初始化新串的值*/ memcpy(buf, msg, len); buf[len] = 0X80; //若buf[len]为带符号字符型, 赋值后将变成负数 memcpy(buf + len + padLen - 8, msgLen, 8); return buf; } /*对需要填充的消息进行数字签名*/ void md5_tail(UINT8 *msg, UINT8 *digest,const UINT32 len, UINT8 *msgLen) { UINT32 padLen, i; UINT8 *buf = NULL; padLen = pad_len(len); buf = tail_pad(msg, msgLen, len, padLen);//填充字符串, 得到新串buf digest_opt(buf, len + padLen); //数字签名计算 encode(INIT, digest, 16); //存储最终结果 free(buf); } /*对消息进行数字签名*/ void md5_msg(UINT8 *msg, UINT8 *digest) { UINT32 len = strlen(msg); //len为当前消息长度 UINT8 msgLen[8]; init_md5(); len_data(msgLen, len); //计算填充的长度信息 md5_tail(msg, digest, len, msgLen); //摘要计算 } /*对文件进行数字签名*/ void md5_file(FILE *fp, UINT8 *digest) { UINT32 bufLen = 0, fileLen = 0; UINT8 buf , msgLen[8]; init_md5(); bufLen = fread(buf, sizeof(UINT8), N, fp); fileLen += bufLen; while(!feof(fp)) { digest_opt(buf, N); bufLen = fread(buf, sizeof(UINT8), N, fp); fileLen += bufLen; } len_data(msgLen, fileLen - 1); //计算填充的长度信息 md5_tail(buf, digest, bufLen - 1, msgLen); //摘要计算 } /*主测试函数*/ int main() { FILE * fp; UINT8 digest[16]; UINT32 i; fp = open("m", "r"); md5_file(fp, digest); close(fp); printf("file\tdigest: "); for(i = 0; i < 16; i++) printf("%02x", digest[i]); printf("\n"); md5_msg("abc", digest); printf("message\tdigest: "); for(i = 0; i < 16; i++) printf("%02x", digest[i]); printf("\n"); return 0; }
相关文章推荐
- 用ASP编写的加密和解密类
- VBS脚本加密/解密VBS脚本(简易免杀版1.1)
- BAT加密工具 EncryBat 非编译型bat批处理加密方案与代码
- C#对称加密(AES加密)每次生成的结果都不同的实现思路和代码实例
- SQLServer 2008中的代码安全(一) 存储过程加密与安全上下文
- 实例讲解SQL Server加密功能
- C#实现对文件进行加密解密的方法
- C#实现数据包加密与解密实例详解
- C#最简单的字符串加密解密方法
- C#加密app.config中连接字符串的方法
- C#使用伪随机数实现加密用户密码的方法
- asp MD5加密方式使用建议
- C#对称加密与非对称加密实例
- C语言压缩文件和用MD5算法校验文件完整性的实例教程
- 浅谈C#中Md5和Sha1两种加密方式
- 基于C#对用户密码使用MD5加密与解密
- vbs shellcode转换escape加密
- .NET实现一机一码加密、把EXE变成图片运行,被破解自动销毁随时授权回收
- PrintStream、MD5、ByteArrayInputStream、 ByteArrayOutputStream、16位流介绍