MD5 电子签名
2016-03-22 09:27
465 查看
MD5 算法
假设我们有 b - bits 的数据,需要计算他的电子签名 , 对于任意的 b ( 甚至可以是 0 , 但是必须是 8 的倍数) 。追加对齐bit数据。
让数据对齐成 模512 byte 剩余448 byte 的长度。 追加数据一定要进行,哪怕数据本来就是模512 byte 剩余448 byte, 也得追加512个byte来对对齐。 追加数据的方式是第一个bit是1 。 其余的bit全部是 0 。追加长度
对于追加了对齐数据后的数据,将原始数据的长度 ( in bits)( 64 bit 数据表示, 小32位在前 )追加到数据后面。这样最终得到512 byte 的倍数的数据。初始化 4 byte 长度的电子签名
先低 byte :word A: 01 23 45 67
word B: 89 ab cd ef
word C: fe dc ba 98
word D: 76 54 32 10
每 16 bytes 走下面的流程 :
。。。 各种扭曲平移。。。将ABCD一次从小的byte 到大依次输出为MD5电子签名
代码
#include <math.h> #include <string.h> #include "md5.h" static const MD5_word A_init = 0x67452301; static const MD5_word B_init = 0xefcdab89; static const MD5_word C_init = 0x98badcfe; static const MD5_word D_init = 0x10325476; static const MD5_word T[65] = { /* 4294967296 * abs( sin ( i ) ) */ 0 , 3614090360, 3905402710, 606105819, 3250441966, 4118548399, 1200080426, 2821735955, 4249261313, 1770035416, 2336552879, 4294925233, 2304563134, 1804603682, 4254626195, 2792965006, 1236535329, 4129170786, 3225465664, 643717713, 3921069994, 3593408605, 38016083, 3634488961, 3889429448, 568446438, 3275163606, 4107603335, 1163531501, 2850285829, 4243563512, 1735328473, 2368359562, 4294588738, 2272392833, 1839030562, 4259657740, 2763975236, 1272893353, 4139469664, 3200236656, 681279174, 3936430074, 3572445317, 76029189, 3654602809, 3873151461, 530742520, 3299628645, 4096336452, 1126891415, 2878612391, 4237533241, 1700485571, 2399980690, 4293915773, 2240044497, 1873313359, 4264355552, 2734768916, 1309151649, 4149444226, 3174756917, 718787259, 3951481745 }; // XY ==> X&Y // not (X) ==> ~X // X v Y ==> X | Y // X xor Y ==> X ^ Y // X <<< s ==> ( X << s ) | ( X >> (32 -s ) ) //F(X,Y,Z) = XY v not(X) Z inline MD5_word F(MD5_word X , MD5_word Y , MD5_word Z) { return X & Y | ~X & Z ; } //G(X,Y,Z) = XZ v Y not(Z) inline MD5_word G(MD5_word X , MD5_word Y , MD5_word Z) { return X & Z ^ Y & ~Z ; } //H(X,Y,Z) = X xor Y xor Z inline MD5_word H(MD5_word X , MD5_word Y , MD5_word Z) { return X ^ Y ^ Z ; } //I(X,Y,Z) = Y xor (X v not(Z)) inline MD5_word I(MD5_word X , MD5_word Y , MD5_word Z) { return Y ^ ( X | ~ Z ) ; } /* Round 1. */ /* Let [abcd k s i] denote the operation a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ #define ROUND1(a,b,c,d,k,s,i) \ a = a + F(b,c,d) + X[k] + T[i] ; \ a = ( a << s | a>>(32 - s) ) + b; /* Round 2. */ /* Let [abcd k s i] denote the operation a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ #define ROUND2(a,b,c,d,k,s,i) \ a = a + G(b,c,d) + X[k] + T[i] ; \ a = ( a << s | a>>(32 - s) ) + b; /* Round 3. */ /* Let [abcd k s t] denote the operation a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ #define ROUND3(a,b,c,d,k,s,i) \ a = a + H(b,c,d) + X[k] + T[i] ; \ a = ( a << s | a>>(32 - s) ) + b; /* Round 4. */ /* Let [abcd k s t] denote the operation a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ #define ROUND4(a,b,c,d,k,s,i) \ a = a + I(b,c,d) + X[k] + T[i] ; \ a = ( a << s | a>>(32 - s) ) + b; void MD5_16Word(const MD5_word X[16] ,struct MD5Content * content) { register MD5_word AA = content->A; register MD5_word BB = content->B; register MD5_word CC = content->C; register MD5_word DD = content->D; ROUND1(AA, BB, CC, DD, 0, 7, 1) ROUND1(DD, AA, BB, CC, 1, 12, 2) ROUND1(CC, DD, AA, BB, 2, 17, 3) ROUND1(BB, CC, DD, AA, 3, 22, 4) ROUND1(AA,BB,CC,DD, 4 , 7, 5 ); ROUND1(DD,AA,BB,CC, 5 , 12, 6); ROUND1(CC,DD,AA,BB, 6 , 17, 7); ROUND1(BB,CC,DD,AA, 7 , 22, 8); ROUND1(AA,BB,CC,DD, 8 , 7, 9 ); ROUND1(DD,AA,BB,CC, 9 , 12, 10); ROUND1(CC,DD,AA,BB, 10 , 17, 11); ROUND1(BB,CC,DD,AA, 11 , 22, 12); ROUND1(AA,BB,CC,DD, 12 , 7, 13 ); ROUND1(DD,AA,BB,CC, 13 , 12, 14); ROUND1(CC,DD,AA,BB, 14 , 17, 15); ROUND1(BB,CC,DD,AA, 15 , 22, 16); ROUND2(AA,BB,CC,DD, 1 , 5, 17 ); ROUND2(DD,AA,BB,CC, 6 , 9, 18); ROUND2(CC,DD,AA,BB, 11 , 14, 19); ROUND2(BB,CC,DD,AA, 0 , 20, 20); ROUND2(AA,BB,CC,DD, 5 , 5, 21 ); ROUND2(DD,AA,BB,CC, 10 , 9, 22); ROUND2(CC,DD,AA,BB, 15 , 14, 23); ROUND2(BB,CC,DD,AA, 4 , 20, 24); ROUND2(AA,BB,CC,DD, 9 , 5, 25 ); ROUND2(DD,AA,BB,CC, 14 , 9, 26); ROUND2(CC,DD,AA,BB, 3 , 14, 27); ROUND2(BB,CC,DD,AA, 8 , 20, 28); ROUND2(AA,BB,CC,DD, 13 , 5, 29 ); ROUND2(DD,AA,BB,CC, 2 , 9, 30); ROUND2(CC,DD,AA,BB, 7 , 14, 31); ROUND2(BB,CC,DD,AA, 12 , 20, 32); ROUND3(AA,BB,CC,DD, 5, 4, 33); ROUND3(DD,AA,BB,CC, 8, 11, 34); ROUND3(CC,DD,AA,BB, 11, 16, 35); ROUND3(BB,CC,DD,AA, 14, 23, 36); ROUND3(AA,BB,CC,DD, 1, 4, 37); ROUND3(DD,AA,BB,CC, 4, 11, 38); ROUND3(CC,DD,AA,BB, 7, 16, 39); ROUND3(BB,CC,DD,AA, 10, 23, 40); ROUND3(AA,BB,CC,DD, 13, 4, 41); ROUND3(DD,AA,BB,CC, 0, 11, 42); ROUND3(CC,DD,AA,BB, 3, 16, 43); ROUND3(BB,CC,DD,AA, 6, 23, 44); ROUND3(AA,BB,CC,DD, 9, 4, 45); ROUND3(DD,AA,BB,CC, 12, 11, 46); ROUND3(CC,DD,AA,BB, 15, 16, 47); ROUND3(BB,CC,DD,AA, 2, 23, 48); ROUND4(AA,BB,CC,DD, 0, 6, 49); ROUND4(DD,AA,BB,CC, 7, 10, 50); ROUND4(CC,DD,AA,BB, 14, 15, 51); ROUND4(BB,CC,DD,AA, 5, 21, 52); ROUND4(AA,BB,CC,DD, 12, 6, 53); ROUND4(DD,AA,BB,CC, 3, 10, 54); ROUND4(CC,DD,AA,BB, 10, 15, 55); ROUND4(BB,CC,DD,AA, 1, 21, 56); ROUND4(AA,BB,CC,DD, 8, 6, 57); ROUND4(DD,AA,BB,CC, 15, 10, 58); ROUND4(CC,DD,AA,BB, 6, 15, 59); ROUND4(BB,CC,DD,AA, 13, 21, 60); ROUND4(AA,BB,CC,DD, 4, 6, 61); ROUND4(DD,AA,BB,CC, 11, 10, 62); ROUND4(CC,DD,AA,BB, 2, 15, 63); ROUND4(BB,CC,DD,AA, 9, 21, 64); content->A += AA; content->B += BB; content->C += CC; content->D += DD; } union MD5Buff { MD5_word words[16]; struct append_buff{ unsigned char chars[56]; MD5_word size[2]; } append; }; void byteSwap(MD5_word *buf, unsigned words){ #ifdef BIG_ENDIAN unsigned char *p = (unsigned char *)buf; do { *buf++ = (MD5_word) ( ((unsigned)p[3] )| ((unsigned) p[2] <<8) | ((unsigned)p[1] << 16 ) | ((unsigned p[0]) << 24 ) ); p += 4; } while (--words); #endif } struct MD5Content MD5(const unsigned char * buff_ , MD5_uint64 size_ ) { MD5Content content; content.A = A_init; content.B = B_init; content.C = C_init; content.D = D_init; MD5_uint64 left_size = size_ ; const unsigned char * next = buff_; MD5Buff buff; while( left_size >= 64 ) { memcpy(buff.words,next,64); byteSwap(buff.words , 16) ; MD5_16Word(buff.words,&content); next += 64 ; left_size -= 64 ; } memset(buff.words , 0 , 64 ); if(left_size > 0 ){ memcpy(buff.append.chars,next,left_size); } buff.append.chars[left_size] = 0x80; if( left_size < 55 ) { buff.append.size[1] = (MD5_word)(((size_<<3) & ( 0xffff0000ULL) ) >> 32 ) ; buff.append.size[0] = (MD5_word)(((size_<<3) & ( 0x0000ffffULL) ) ) ; } byteSwap(buff.words , 16) ; MD5_16Word(buff.words,&content); if( left_size > 55) { memset(buff.words , 0 , 64 ); buff.append.size[1] = (MD5_word)((size_<<3 & ( 0xffff0000ULL) ) >> 32 ) ; buff.append.size[0] = (MD5_word)((size_<<3 & ( 0x0000ffffULL) ) ) ; byteSwap(buff.words , 16) ; MD5_16Word(buff.words,&content); } return content; } inline std::string GetMD5(unsigned char *buf, size_t len) { auto content = MD5((unsigned char *)buf, (unsigned long long ) len ); MD5Result ret; ret.content = content; std::ostringstream ost; for( int i = 0 ; i < 16 ; i ++ ) { ost.width(2); ost.fill('0'); ost<<std::hex<<short(ret.buff[i]); } return ost.str(); }
相关文章推荐
- AndroidStudio常见提示
- iOS Provisioning Profile(Certificate)与Code Signing详解
- Android23版本应用使用HttpClient
- vi设置
- Volley加载网络图片
- 关于自学activiti开源流程引擎的一点点感悟和代码分享demo教程
- 原生的强大DOM选择器querySelector
- 利用python进行数据分析之数据聚合和分组运算
- [Unity] Unity3D研究院编辑器之独立Inspector属性
- .gitignore 配置
- 快速排序
- 字符编码
- HTML5- Canvas入门(一)
- container_of()宏
- 一致性hash算法
- CSS hack
- 2015-2016 下半学期 第二周 训练
- perl 创建包
- perl 创建包
- perl 创建包