首页 > 代码库 > RFC1321 MD5加密算法

RFC1321 MD5加密算法

global.h

 1 /* GLOBAL.H - RSAREF types and constants 2  */ 3  4 /* PROTOTYPES should be set to one if and only if the compiler supports 5 function argument prototyping. 6 The following makes PROTOTYPES default to 0 if it has not already 7 been defined with C compiler flags. 8  */ 9  10 #ifndef PROTOTYPES11 #define PROTOTYPES 012 #endif13 14 /* POINTER defines a generic pointer type */15 typedef unsigned char *POINTER;16 17 /* UINT2 defines a two byte word */18 typedef unsigned short int UINT2;19 20 /* UINT4 defines a four byte word */21 typedef unsigned long int UINT4;22 23 /* PROTO_LIST is defined depending on how PROTOTYPES is defined above.24 If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it25 returns an empty list.26  */27 #if PROTOTYPES28 #define PROTO_LIST(list) list29 #else30 #define PROTO_LIST(list) ()31 #endif

 

md5.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 software10 or this function.11 12 License is also granted to make and use derivative works provided13 that such works are identified as "derived from the RSA Data14 Security, Inc. MD5 Message-Digest Algorithm" in all material15 mentioning or referencing the derived work.16 17 RSA Data Security, Inc. makes no representations concerning either18 the merchantability of this software or the suitability of this19 software for any particular purpose. It is provided "as is"20 without express or implied warranty of any kind.21 These notices must be retained in any copies of any part of this22 documentation and/or software.23  */24 25 #include "global.h"26 27 /* MD5 context. */28 typedef struct {29     UINT4 state[4];                                    /* state (ABCD) */30     UINT4 count[2];                                    /* number of bits, modulo 2^64 (lsb first) */31     unsigned char buffer[64];                        /* input buffer */32 } MD5_CTX;33 34 void MD5Init(MD5_CTX *);35 void MD5Update(MD5_CTX *, unsigned char *, unsigned int);36 void MD5Final(unsigned char [16], MD5_CTX *);

 

md5c.c

  1 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm  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 #include "global.h" 27 #include "md5.h" 28  29 /* Constants for MD5Transform routine. 30  */ 31 #define S11 7 32 #define S12 12 33 #define S13 17 34 #define S14 22 35 #define S21 5 36 #define S22 9 37 #define S23 14 38 #define S24 20 39 #define S31 4 40 #define S32 11 41 #define S33 16 42 #define S34 23 43 #define S41 6 44 #define S42 10 45 #define S43 15 46 #define S44 21 47  48 static void MD5Transform(UINT4 [4], unsigned char [64]); 49 static void Encode(unsigned char *, UINT4 *, unsigned int); 50 static void Decode(UINT4 *, unsigned char *, unsigned int); 51 static void MD5_memcpy(POINTER, POINTER, unsigned int); 52 static void MD5_memset(POINTER, int, unsigned int); 53  54 static unsigned char PADDING[64] = { 55   0x80, 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, 0, 0, 0, 0, 57   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 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 /* ROTATE_LEFT rotates x left n bits. 68  */ 69 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 70  71 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. 72 Rotation is separate from addition to prevent recomputation. 73  */ 74 #define FF(a, b, c, d, x, s, ac) {  75  (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac);  76  (a) = ROTATE_LEFT ((a), (s));  77  (a) += (b);  78   } 79  80 #define GG(a, b, c, d, x, s, ac) {  81  (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac);  82  (a) = ROTATE_LEFT ((a), (s));  83  (a) += (b);  84   } 85  86 #define HH(a, b, c, d, x, s, ac) {  87  (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac);  88  (a) = ROTATE_LEFT ((a), (s));  89  (a) += (b);  90   } 91  92 #define II(a, b, c, d, x, s, ac) {  93  (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac);  94  (a) = ROTATE_LEFT ((a), (s));  95  (a) += (b);  96   } 97  98 /* MD5 initialization. Begins an MD5 operation, writing a new context. 99  */100 void MD5Init (MD5_CTX *context)101 {102     context->count[0] = context->count[1] = 0;103     /* Load magic initialization constants.104     */105     context->state[0] = 0x67452301;106     context->state[1] = 0xefcdab89;107     context->state[2] = 0x98badcfe;108     context->state[3] = 0x10325476;109 }110 111 /* MD5 block update operation. Continues an MD5 message-digest112   operation, processing another message block, and updating the113   context.114  */115 void MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen)116 {117     unsigned int i, index, partLen;118 119     /* Compute number of bytes mod 64 */120     index = (unsigned int)((context->count[0] >> 3) & 0x3F);121 122     /* Update number of bits */123     if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3))124     {125         context->count[1]++;126     }127     context->count[1] += ((UINT4)inputLen >> 29);128 129     partLen = 64 - index;130 131     /* Transform as many times as possible.132     */133     if (inputLen >= partLen) 134     {135         MD5_memcpy ((POINTER)&context->buffer[index], (POINTER)input, partLen);136         MD5Transform (context->state, context->buffer);137 138         for (i = partLen; i + 63 < inputLen; i += 64)139         {140             MD5Transform (context->state, &input[i]);141         }142 143         index = 0;144     }145     else146     {147         i = 0;148     }149     150     /* Buffer remaining input */151     MD5_memcpy((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i);152 }153 154 /* MD5 finalization. Ends an MD5 message-digest operation, writing the155   the message digest and zeroizing the context.156  */157 void MD5Final (unsigned char digest[16], MD5_CTX *context)158 {159     unsigned char bits[8];160     unsigned int index, padLen;161 162     /* Save number of bits */163     Encode (bits, context->count, 8);164 165     /* Pad out to 56 mod 64.166     */167     index = (unsigned int)((context->count[0] >> 3) & 0x3f);168     padLen = (index < 56) ? (56 - index) : (120 - index);169     MD5Update (context, PADDING, padLen);170 171     /* Append length (before padding) */172     MD5Update (context, bits, 8);173 174     /* Store state in digest */175     Encode (digest, context->state, 16);176 177     /* Zeroize sensitive information.178     */179     MD5_memset ((POINTER)context, 0, sizeof (*context));180 }181 182 /* MD5 basic transformation. Transforms state based on block.183  */184 static void MD5Transform (UINT4 state[4], unsigned char block[64])185 {186     UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];187 188     Decode (x, block, 64);189 190     /* Round 1 */191     FF (a, b, c, d, x[ 0], S11, 0xd76aa478);        /* 1 */192     FF (d, a, b, c, x[ 1], S12, 0xe8c7b756);        /* 2 */193     FF (c, d, a, b, x[ 2], S13, 0x242070db);        /* 3 */194     FF (b, c, d, a, x[ 3], S14, 0xc1bdceee);        /* 4 */195     FF (a, b, c, d, x[ 4], S11, 0xf57c0faf);            /* 5 */196     FF (d, a, b, c, x[ 5], S12, 0x4787c62a);        /* 6 */197     FF (c, d, a, b, x[ 6], S13, 0xa8304613);        /* 7 */198     FF (b, c, d, a, x[ 7], S14, 0xfd469501);        /* 8 */199     FF (a, b, c, d, x[ 8], S11, 0x698098d8);        /* 9 */200     FF (d, a, b, c, x[ 9], S12, 0x8b44f7af);        /* 10 */201     FF (c, d, a, b, x[10], S13, 0xffff5bb1);            /* 11 */202     FF (b, c, d, a, x[11], S14, 0x895cd7be);        /* 12 */203     FF (a, b, c, d, x[12], S11, 0x6b901122);        /* 13 */204     FF (d, a, b, c, x[13], S12, 0xfd987193);        /* 14 */205     FF (c, d, a, b, x[14], S13, 0xa679438e);        /* 15 */206     FF (b, c, d, a, x[15], S14, 0x49b40821);        /* 16 */207 208     /* Round 2 */209     GG (a, b, c, d, x[ 1], S21, 0xf61e2562);        /* 17 */210     GG (d, a, b, c, x[ 6], S22, 0xc040b340);        /* 18 */211     GG (c, d, a, b, x[11], S23, 0x265e5a51);        /* 19 */212     GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa);        /* 20 */213     GG (a, b, c, d, x[ 5], S21, 0xd62f105d);        /* 21 */214     GG (d, a, b, c, x[10], S22,  0x2441453);        /* 22 */215     GG (c, d, a, b, x[15], S23, 0xd8a1e681);        /* 23 */216     GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8);        /* 24 */217     GG (a, b, c, d, x[ 9], S21, 0x21e1cde6);        /* 25 */218     GG (d, a, b, c, x[14], S22, 0xc33707d6);        /* 26 */219     GG (c, d, a, b, x[ 3], S23, 0xf4d50d87);        /* 27 */220 221     GG (b, c, d, a, x[ 8], S24, 0x455a14ed);        /* 28 */222     GG (a, b, c, d, x[13], S21, 0xa9e3e905);        /* 29 */223     GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8);        /* 30 */224     GG (c, d, a, b, x[ 7], S23, 0x676f02d9);        /* 31 */225     GG (b, c, d, a, x[12], S24, 0x8d2a4c8a);        /* 32 */226 227     /* Round 3 */228     HH (a, b, c, d, x[ 5], S31, 0xfffa3942);        /* 33 */229     HH (d, a, b, c, x[ 8], S32, 0x8771f681);        /* 34 */230     HH (c, d, a, b, x[11], S33, 0x6d9d6122);        /* 35 */231     HH (b, c, d, a, x[14], S34, 0xfde5380c);        /* 36 */232     HH (a, b, c, d, x[ 1], S31, 0xa4beea44);        /* 37 */233     HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9);        /* 38 */234     HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60);        /* 39 */235     HH (b, c, d, a, x[10], S34, 0xbebfbc70);        /* 40 */236     HH (a, b, c, d, x[13], S31, 0x289b7ec6);        /* 41 */237     HH (d, a, b, c, x[ 0], S32, 0xeaa127fa);        /* 42 */238     HH (c, d, a, b, x[ 3], S33, 0xd4ef3085);        /* 43 */239     HH (b, c, d, a, x[ 6], S34,  0x4881d05);        /* 44 */240     HH (a, b, c, d, x[ 9], S31, 0xd9d4d039);        /* 45 */241     HH (d, a, b, c, x[12], S32, 0xe6db99e5);        /* 46 */242     HH (c, d, a, b, x[15], S33, 0x1fa27cf8);        /* 47 */243     HH (b, c, d, a, x[ 2], S34, 0xc4ac5665);        /* 48 */244 245     /* Round 4 */246     II (a, b, c, d, x[ 0], S41, 0xf4292244);        /* 49 */247     II (d, a, b, c, x[ 7], S42, 0x432aff97);            /* 50 */248     II (c, d, a, b, x[14], S43, 0xab9423a7);        /* 51 */249     II (b, c, d, a, x[ 5], S44, 0xfc93a039);        /* 52 */250     II (a, b, c, d, x[12], S41, 0x655b59c3);        /* 53 */251     II (d, a, b, c, x[ 3], S42, 0x8f0ccc92);            /* 54 */252     II (c, d, a, b, x[10], S43, 0xffeff47d);            /* 55 */253     II (b, c, d, a, x[ 1], S44, 0x85845dd1);        /* 56 */254     II (a, b, c, d, x[ 8], S41, 0x6fa87e4f);            /* 57 */255     II (d, a, b, c, x[15], S42, 0xfe2ce6e0);        /* 58 */256     II (c, d, a, b, x[ 6], S43, 0xa3014314);        /* 59 */257     II (b, c, d, a, x[13], S44, 0x4e0811a1);        /* 60 */258     II (a, b, c, d, x[ 4], S41, 0xf7537e82);        /* 61 */259     II (d, a, b, c, x[11], S42, 0xbd3af235);        /* 62 */260     II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb);        /* 63 */261     II (b, c, d, a, x[ 9], S44, 0xeb86d391);        /* 64 */262 263     state[0] += a;264     state[1] += b;265     state[2] += c;266     state[3] += d;267 268     /* Zeroize sensitive information.269     */270     MD5_memset ((POINTER)x, 0, sizeof (x));271 }272 273 /* Encodes input (UINT4) into output (unsigned char). Assumes len is274   a multiple of 4.275  */276 static void Encode (unsigned char *output, UINT4 *input, unsigned int len)277 {278     unsigned int i, j;279 280     for (i = 0, j = 0; j < len; i++, j += 4) 281     {282         output[j] = (unsigned char)(input[i] & 0xff);283         output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);284         output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);285         output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);286     }287 }288 289 /* Decodes input (unsigned char) into output (UINT4). Assumes len is290   a multiple of 4.291  */292 static void Decode (UINT4 *output, unsigned char *input, unsigned int len)293 {294     unsigned int i, j;295 296     for (i = 0, j = 0; j < len; i++, j += 4)297     {298         output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);299     }300 }301 302 /* Note: Replace "for loop" with standard memcpy if possible.303  */304 static void MD5_memcpy (POINTER output, POINTER input, unsigned int len)305 {306     unsigned int i;307 308     for (i = 0; i < len; i++)309     {310         output[i] = input[i];311     }312 }313 314 /* Note: Replace "for loop" with standard memset if possible.315  */316 static void MD5_memset (POINTER output, int value, unsigned int len)317 {318     unsigned int i;319 320     for (i = 0; i < len; i++)321     {322         ((char *)output)[i] = (char)value;323     }324     325 }

 

mddriver.c

  1 /* MDDRIVER.C - test driver for MD2, MD4 and MD5  2  */  3   4 /* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All  5 rights reserved.  6   7 RSA Data Security, Inc. makes no representations concerning either  8 the merchantability of this software or the suitability of this  9 software for any particular purpose. It is provided "as is" 10 without express or implied warranty of any kind. 11  12 These notices must be retained in any copies of any part of this 13 documentation and/or software. 14  */ 15  16 /* The following makes MD default to MD5 if it has not already been 17   defined with C compiler flags. 18  */ 19 #ifndef MD 20 #define MD 5 21 #endif 22  23 #include <stdio.h> 24 #include <time.h> 25 #include <string.h> 26 #include <stdlib.h> 27 #include <Windows.h> 28 #include "global.h" 29 #include "md5.h" 30  31 /* Length of test block, number of test blocks. 32  */ 33 #define TEST_BLOCK_LEN 1000 34 #define TEST_BLOCK_COUNT 1000 35  36 static void MDString(char *); 37 static void MDTimeTrial(void); 38 static void MDTestSuite(void); 39 static void MDFile(char *); 40 static void MDFilter(void); 41 static void MDPrint(unsigned char [16]); 42  43 #define MD_CTX MD5_CTX 44 #define MDInit MD5Init 45 #define MDUpdate MD5Update 46 #define MDFinal MD5Final 47  48  49 /* Main driver. 50 Arguments (may be any combination): 51   -sstring    - digests string 52   -t            - runs time trial 53   -x            - runs test script 54   filename    - digests file 55   (none)        - digests standard input 56  */ 57 int main (int argc, char *argv[]) 58 { 59     int i; 60  61     if (argc > 1) 62     { 63         for (i = 1; i < argc; i++) 64         { 65             if (argv[i][0] == - && argv[i][1] == s) 66             { 67                 MDString (argv[i] + 2); 68             } 69             else if (strcmp (argv[i], "-t") == 0) 70             { 71                 MDTimeTrial (); 72             } 73             else if (strcmp (argv[i], "-x") == 0) 74             { 75                 MDTestSuite (); 76             } 77             else 78             { 79                 MDFile (argv[i]); 80             } 81         } 82     } 83     else 84     { 85         MDFilter (); 86     } 87  88     return (0); 89 } 90  91 /* Digests a string and prints the result. 92  */ 93 static void MDString(char *string) 94 { 95     MD_CTX context; 96     unsigned char digest[16]; 97     unsigned int len = strlen (string); 98  99     MDInit (&context);100     MDUpdate (&context, string, len);101     MDFinal (digest, &context);102 103     printf ("MD%d (\"%s\") = ", MD, string);104     MDPrint (digest);105     printf ("\n");106 }107 108 /* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte109   blocks.110  */111 static void MDTimeTrial ()112 {113     MD_CTX context;114     time_t endTime, startTime;115     unsigned char block[TEST_BLOCK_LEN], digest[16];116     unsigned int i;117     printf("MD%d time trial. Digesting %d %d-byte blocks ...", MD, TEST_BLOCK_LEN, TEST_BLOCK_COUNT);118 119     /* Initialize block */120     for (i = 0; i < TEST_BLOCK_LEN; i++)121     {122         block[i] = (unsigned char)(i & 0xff);123     }124     125     /* Start timer */126     time (&startTime);127 128     /* Digest blocks */129     MDInit (&context);130     for (i = 0; i < TEST_BLOCK_COUNT; i++)131     {132         MDUpdate (&context, block, TEST_BLOCK_LEN);133     }134     MDFinal (digest, &context);135 136     Sleep(2000);137     /* Stop timer */138     time (&endTime);139 140     printf (" done\n");141     printf ("Digest = ");142     MDPrint (digest);143     printf ("\nTime = %ld seconds\n", (long)(endTime-startTime));144     printf("Speed = %ld bytes/second\n", (long)TEST_BLOCK_LEN * (long)TEST_BLOCK_COUNT/(endTime-startTime));145 }146 147 /* Digests a reference suite of strings and prints the results.148  */149 static void MDTestSuite ()150 {151     printf ("MD%d test suite:\n", MD);152 153     MDString("");154     MDString("a");155     MDString("abc");156     MDString("message digest");157     MDString("abcdefghijklmnopqrstuvwxyz");158     MDString("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");159     MDString("12345678901234567890123456789012345678901234567890123456789012345678901234567890");160 }161 162 /* Digests a file and prints the result.163 */164 static void MDFile (char *filename)165 {166     FILE *file;167     MD_CTX context;168     int len;169     unsigned char buffer[1024], digest[16];170 171     if ((file = fopen (filename, "rb")) == NULL)172     {173         printf ("%s can‘t be opened\n", filename);174     }175     else 176     {177         MDInit (&context);178 179         while (len = fread (buffer, 1, 1024, file))180         {181             MDUpdate (&context, buffer, len);182         }183         184         MDFinal(digest, &context);185 186         fclose (file);187 188         printf ("MD%d (%s) = ", MD, filename);189         MDPrint (digest);190         printf ("\n");191     }192 }193 194 /* Digests the standard input and prints the result.195  */196 static void MDFilter ()197 {198     MD_CTX context;199     int len;200     unsigned char buffer[16], digest[16];201 202     MDInit (&context);203     204     while (len = fread (buffer, 1, 16, stdin))205     {206         MDUpdate (&context, buffer, len);207     }208 209     MDFinal (digest, &context);210 211     MDPrint (digest);212     printf ("\n");213 }214 215 /* Prints a message digest in hexadecimal.216  */217 static void MDPrint (unsigned char digest[16])218 {219     unsigned int i;220 221     for (i = 0; i < 16; i++)222     {223         printf ("%02x", digest[i]);224     }225     226 }