当前位置:首页 > MD5 报文摘要算法源码
本附录包括以下文件:(摘自RSAREF: A Cryptographic Toolkit for Privacy-Enhanced Mail:) global.h - 全局头文件 md5.h -- MD5头文件 md5c.c -- MD5源代码
(要得到更多的RSAREF信息,请发e-mai到:
mddriver.c-MD2, MD4 and MD5的测试驱动程序。 驱动程序默认情况下编译MD5,但如果在C的编译命令行将MD5参数设成2或4,则也可以编译 MD2和MD4
此应用程序是方便使用的,可用在不同的平台上,在特殊的平台上优化它也并不困难,这留给读
者作为练习。例如,在“little-endian”平台上,此平台32位字的最低地址字节最无意义的字节,
并且没有队列限制,在MD5变换中的解码的命令调用可以被相应的类型替代。 A1 global.h
/* GLOBAL.H - RSAREF 类型和常数*/
/* 当且仅当编译器支持函数原型的声明时,PROTOTYPES必须被设置一次 如果还没有定义C编译器的标记,下面的代码使PROTOTYPES置为0。*/ #ifndef PROTOTYPES #define PROTOTYPES 0 #endif
/* POINTER 定义成一个普通的指针类型 */ typedef unsigned char *POINTER;
/* UINT2 定义成两字节的字 */
typedef unsigned short int UINT2;
/* UINT4定一成四字节的字 */ typedef unsigned long int UINT4; /* PROTO_LIST的定义依赖于上面PROTOTYPES的定义,如果使用了PROTOTYPES,那么
PROTO_LIST返回此列表,否则返回一个空列表。*/ #if PROTOTYPES
#define PROTO_LIST(list) list #else
#define PROTO_LIST(list) () #endif A.2 md5.h
/*MD5.H - MD5C.C头文件*/
/*本软件允许被复制或运用,但必须在所有提及和参考的地方标注“RSA Data
Security, Inc. MD5 Message-Digest Algorithm”,也允许产生或运用派生软件,但必须在所有提及和参考的地方标明 “derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm” RSA数据安全公司(RSA Data Security, Inc.)从来没有出于任何特定目的陈述过关于此
软件的可买性和实用性,它提供了“as is”,没有表达或暗示过任何理由。 此声明必须在任何此文件和软件的任何拷贝中保留。*/
/* MD5 context. */ typedef struct {
UINT4 state[4]; /* state (ABCD) */ UINT4 count[2]; /* 位数量, 模 2^64 (低位在前) */
unsigned char buffer[64]; /* 输入缓冲器 */ } MD5_CTX;
void MD5Init PROTO_LIST ((MD5_CTX *)); void MD5Update PROTO_LIST
((MD5_CTX *, unsigned char *, unsigned int));
void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *)); A.3 md5c.c
/* MD5C.C – RSA数据安全公司,MD5报文摘要算法*/
/*本软件允许被复制或运用,但必须在所有提及和参考的地方标注“RSA Data Security, Inc. MD5 Message-Digest Algorithm”也允许产生或运用派生软件,但必须在所有提及和参考的地方标明
“derived from the RSA Data RSA数据安全公司(RSA Data Security, Inc.)从来没有出于任何
特定目的陈述过关于此软件的可买性和实用性,它提供了“as is”,没有表达或暗示过任何理由。
此声明必须在任何此文件和软件的任何拷贝中保留。*/
#include \#include \
/* Constants for MD5Transform routine. */
#define S11 7 #define S12 12 #define S13 17 #define S14 22
#define S21 5 #define S22 9 #define S23 14 #define S24 20 #define S31 4 #define S32 11 #define S33 16 #define S34 23 #define S41 6 #define S42 10 #define S43 15 #define S44 21
static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64])); static void Encode PROTO_LIST
((unsigned char *, UINT4 *, unsigned int)); static void Decode PROTO_LIST
((UINT4 *, unsigned char *, unsigned int));
static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
/* F, G, H 和 I 是基本MD5函数 */
#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)))
/* ROTATE_LEFT 将x循环左移n位 */
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* 循环从加法中分离出是为了防止重复计算*/ #define FF(a, b, c, d, x, s, ac) { \\
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \\ (a) = ROTATE_LEFT ((a), (s)); \\ (a) += (b); \\ }
#define GG(a, b, c, d, x, s, ac) { \\
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \\
(a) = ROTATE_LEFT ((a), (s)); \\ (a) += (b); \\ }
#define HH(a, b, c, d, x, s, ac) { \\
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \\ (a) = ROTATE_LEFT ((a), (s)); \\ (a) += (b); \\ }
#define II(a, b, c, d, x, s, ac) { \\
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \\ (a) = ROTATE_LEFT ((a), (s)); \\ (a) += (b); \\ }
/* MD5 初始化. 开始一个MD5操作写一个新的context. */ void MD5Init (context)
MD5_CTX *context; /* context */ {
context->count[0] = context->count[1] = 0; context->state[0] = 0x67452301; context->state[1] = 0xefcdab89; context->state[2] = 0x98badcfe; context->state[3] = 0x10325476; }
/*MD5 分组更新操作. 继续一个MD5操作,处理另一个消息分组并更新context. */
void MD5Update (context, input, inputLen)
MD5_CTX *context; /* context */ unsigned char *input; /* 输入分组*/ unsigned int inputLen; /* 输入的分组的长度 */ {
unsigned int i, index, partLen;
/* 计算字节数模64的值 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((UINT4)inputLen << 3))
< ((UINT4)inputLen << 3)) context->count[1]++;
context->count[1] += ((UINT4)inputLen >> 29);
共分享92篇相关文档