环境:vc2003
.h
1 /* MD5.H - header file for MD5C.C 2 */ 3 4 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All 5 rights reserved. 6 7 License to copy and use this software is granted provided that it 8 is identified as the "RSA Data Security, Inc. MD5 Message-Digest 9 Algorithm" in all material mentioning or referencing this software 10 or this function. 11 12 License is also granted to make and use derivative works provided 13 that such works are identified as "derived from the RSA Data 14 Security, Inc. MD5 Message-Digest Algorithm" in all material 15 mentioning or referencing the derived work. 16 17 RSA Data Security, Inc. makes no representations concerning either 18 the merchantability of this software or the suitability of this 19 software for any particular purpose. It is provided "as is" 20 without express or implied warranty of any kind. 21 22 These notices must be retained in any copies of any part of this 23 documentation and/or software. 24 */ 25 26 #ifndef MD5_SECRIT_H__ 27 #define MD5_SECRIT_H__ 28 29 namespace SECRIET 30 { 31 /* MD5 context. */ 32 typedef unsigned int uint32_t; 33 typedef struct { 34 uint32_t state[4]; /* state (ABCD) */ 35 uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ 36 unsigned char buffer[64]; /* input buffer */ 37 } MD5_CTX; 38 39 void MD5Init(MD5_CTX *context); 40 void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputLen); 41 void MD5Final(unsigned char digest[16], MD5_CTX *context); 42 43 class CMD5 44 { 45 public: 46 MD5_CTX _ctxMd5; 47 48 public: 49 CMD5() {MD5Init(&_ctxMd5);} 50 ~CMD5() {} 51 52 public: 53 void Encode( unsigned char *input, unsigned int inputLen, unsigned char digest[16] ) 54 { 55 MD5Update( &_ctxMd5, input, inputLen ); 56 MD5Final( digest, &_ctxMd5); 57 } 58 59 }; 60 } 61 #endif
.cpp
1 /* 2 * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm 3 */ 4 5 /* 6 * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights 7 * reserved. 8 * 9 * License to copy and use this software is granted provided that it is 10 * identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" 11 * in all material mentioning or referencing this software or this function. 12 * 13 * License is also granted to make and use derivative works provided that such 14 * works are identified as "derived from the RSA Data Security, Inc. MD5 15 * Message-Digest Algorithm" in all material mentioning or referencing the 16 * derived work. 17 * 18 * RSA Data Security, Inc. makes no representations concerning either the 19 * merchantability of this software or the suitability of this software for 20 * any particular purpose. It is provided "as is" without express or implied 21 * warranty of any kind. 22 * 23 * These notices must be retained in any copies of any part of this 24 * documentation and/or software. 25 */ 26 27 #include "Stdafx.h" 28 #include "md5.h" 29 30 /* 31 * Constants for MD5Transform routine. 32 */ 33 #define S11 7 34 #define S12 12 35 #define S13 17 36 #define S14 22 37 #define S21 5 38 #define S22 9 39 #define S23 14 40 #define S24 20 41 #define S31 4 42 #define S32 11 43 #define S33 16 44 #define S34 23 45 #define S41 6 46 #define S42 10 47 #define S43 15 48 #define S44 21 49 50 namespace SECRIET 51 { 52 53 static unsigned char PADDING[64] = { 54 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 57 }; 58 59 /* 60 * F, G, H and I are basic MD5 functions. 61 */ 62 #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 63 #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 64 #define H(x, y, z) ((x) ^ (y) ^ (z)) 65 #define I(x, y, z) ((y) ^ ((x) | (~z))) 66 67 /* 68 * ROTATE_LEFT rotates x left n bits. 69 */ 70 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 71 72 /* 73 * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is 74 * separate from addition to prevent recomputation. 75 */ 76 #define FF(a, b, c, d, x, s, ac) { \ 77 (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \ 78 (a) = ROTATE_LEFT ((a), (s)); \ 79 (a) += (b); \ 80 } 81 #define GG(a, b, c, d, x, s, ac) { \ 82 (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \ 83 (a) = ROTATE_LEFT ((a), (s)); \ 84 (a) += (b); \ 85 } 86 #define HH(a, b, c, d, x, s, ac) { \ 87 (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \ 88 (a) = ROTATE_LEFT ((a), (s)); \ 89 (a) += (b); \ 90 } 91 #define II(a, b, c, d, x, s, ac) { \ 92 (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \ 93 (a) = ROTATE_LEFT ((a), (s)); \ 94 (a) += (b); \ 95 } 96 97 /* 98 * Encodes input (uint32_t) into output (unsigned char). Assumes len is a 99 * multiple of 4. 100 */ 101 static void 102 Encode(unsigned char *output, uint32_t * input, unsigned int len) 103 { 104 unsigned int i, j; 105 106 // ASSERT((len % 4) == 0); 107 108 for (i = 0, j = 0; j < len; i++, j += 4) { 109 output[j] = (unsigned char) (input[i] & 0xff); 110 output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff); 111 output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff); 112 output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff); 113 } 114 } 115 116 /* 117 * Decodes input (unsigned char) into output (uint32_t). Assumes len is a 118 * multiple of 4. 119 */ 120 static void 121 Decode(uint32_t * output, unsigned char *input, unsigned int len) 122 { 123 unsigned int i, j; 124 125 for (i = 0, j = 0; j < len; i++, j += 4) 126 output[i] = ((uint32_t) input[j]) | (((uint32_t) input[j + 1]) << 8) | 127 (((uint32_t) input[j + 2]) << 16) | (((uint32_t) input[j + 3]) << 24); 128 } 129 130 /* 131 * MD5 basic transformation. Transforms state based on block. 132 */ 133 static void 134 MD5Transform(uint32_t state[4], unsigned char block[64]) 135 { 136 uint32_t a = state[0], b = state[1], c = state[2], d = state[3], 137 x[16]; 138 139 Decode(x, block, 64); 140 141 /* Round 1 */ 142 FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */ 143 FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */ 144 FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */ 145 FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */ 146 FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */ 147 FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */ 148 FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */ 149 FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */ 150 FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */ 151 FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */ 152 FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 153 FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 154 FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 155 FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 156 FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 157 FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 158 159 /* Round 2 */ 160 GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */ 161 GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */ 162 GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 163 GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */ 164 GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */ 165 GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */ 166 GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 167 GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */ 168 GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */ 169 GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 170 GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */ 171 GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */ 172 GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 173 GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */ 174 GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */ 175 GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 176 177 /* Round 3 */ 178 HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */ 179 HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */ 180 HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 181 HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 182 HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */ 183 HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */ 184 HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */ 185 HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 186 HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 187 HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */ 188 HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */ 189 HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */ 190 HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */ 191 HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 192 HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 193 HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */ 194 195 /* Round 4 */ 196 II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */ 197 II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */ 198 II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 199 II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */ 200 II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 201 II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */ 202 II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 203 II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */ 204 II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */ 205 II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 206 II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */ 207 II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 208 II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */ 209 II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 210 II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */ 211 II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */ 212 213 state[0] += a; 214 state[1] += b; 215 state[2] += c; 216 state[3] += d; 217 218 /* 219 * Zeroize sensitive information. 220 */ 221 memset((unsigned char *) x, 0, sizeof(x)); 222 } 223 224 /** 225 * MD5Init: 226 * @context: MD5 context to be initialized. 227 * 228 * Initializes MD5 context for the start of message digest computation. 229 **/ 230 void 231 MD5Init(MD5_CTX * context) 232 { 233 context->count[0] = context->count[1] = 0; 234 /* Load magic initialization constants. */ 235 context->state[0] = 0x67452301; 236 context->state[1] = 0xefcdab89; 237 context->state[2] = 0x98badcfe; 238 context->state[3] = 0x10325476; 239 } 240 241 /** 242 * MD5Update: 243 * @context: MD5 context to be updated. 244 * @input: pointer to data to be fed into MD5 algorithm. 245 * @inputLen: size of @input data in bytes. 246 * 247 * MD5 block update operation. Continues an MD5 message-digest operation, 248 * processing another message block, and updating the context. 249 **/ 250 251 void 252 MD5Update(MD5_CTX * context, unsigned char *input, unsigned int inputLen) 253 { 254 unsigned int i, index, partLen; 255 256 /* Compute number of bytes mod 64 */ 257 index = (unsigned int) ((context->count[0] >> 3) & 0x3F); 258 259 /* Update number of bits */ 260 if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) { 261 context->count[1]++; 262 } 263 context->count[1] += ((uint32_t) inputLen >> 29); 264 265 partLen = 64 - index; 266 267 /* Transform as many times as possible. */ 268 if (inputLen >= partLen) { 269 memcpy((unsigned char *) & context->buffer[index], (unsigned char *) input, partLen); 270 MD5Transform(context->state, context->buffer); 271 272 for (i = partLen; i + 63 < inputLen; i += 64) { 273 MD5Transform(context->state, &input[i]); 274 } 275 index = 0; 276 } else { 277 i = 0; 278 } 279 /* Buffer remaining input */ 280 if ((inputLen - i) != 0) { 281 memcpy((unsigned char *) & context->buffer[index], (unsigned char *) & input[i], inputLen - i); 282 } 283 } 284 285 /** 286 * MD5Final: 287 * @digest: 16-byte buffer to write MD5 checksum. 288 * @context: MD5 context to be finalized. 289 * 290 * Ends an MD5 message-digest operation, writing the the message 291 * digest and zeroing the context. The context must be initialized 292 * with MD5Init() before being used for other MD5 checksum calculations. 293 **/ 294 295 void 296 MD5Final(unsigned char digest[16], MD5_CTX * context) 297 { 298 unsigned char bits[8]; 299 unsigned int index, padLen; 300 301 /* Save number of bits */ 302 Encode(bits, context->count, 8); 303 304 /* 305 * Pad out to 56 mod 64. 306 */ 307 index = (unsigned int) ((context->count[0] >> 3) & 0x3f); 308 padLen = (index < 56) ? (56 - index) : (120 - index); 309 MD5Update(context, PADDING, padLen); 310 311 /* Append length (before padding) */ 312 MD5Update(context, bits, 8); 313 /* Store state in digest */ 314 Encode(digest, context->state, 16); 315 316 /* 317 * Zeroize sensitive information. 318 */ 319 memset((unsigned char *) context, 0, sizeof(*context)); 320 } 321 322 }