MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。这套算法的程序在 RFC 1321 标准中被加以规范。1996年后该算法被证实存在弱点,可以被加以破解,对于需要高度安全性的数据,专家一般建议改用其他算法,如SHA-2。2004年,证实MD5算法无法防止碰撞(collision),因此不适用于安全性认证,如SSL公开密钥认证或是数字签名等用途。
本文假设你已经安装好了OpenSSL,并且持有一份1.1.1的源码。
MD5相关的头文件在md5.h中、源文件在crypto/md5目录中。
主要结构:
# define MD5_LONG unsigned int
# define MD5_CBLOCK 64
# define MD5_LBLOCK (MD5_CBLOCK/4)
# define MD5_DIGEST_LENGTH 16
typedef struct MD5state_st {
MD5_LONG A, B, C, D;
MD5_LONG Nl, Nh;
MD5_LONG data[MD5_LBLOCK];
unsigned int num;
} MD5_CTX;
这个结构定义了MD5运算的海棉算法上下文。主要字段含义:
A, B, C, D —— 存放海棉运算的中间结果。
data —— 数据分组缓冲区,用于暂存不够分组大小的数据。
num —— 缓冲区数据大小。
在1.1.1中,大多数的数据结构已经不再向使用者开放,从封装的角度来看,这是更合理的。如果你在头文件中找不到结构定义,不妨去源码中搜一搜。
主要函数:
int MD5_Init(MD5_CTX *c);
初使化MD5上下文结构。
总是返回1。
int MD5_Update(MD5_CTX *c, const void *data, size_t len);
向MD5上下文输入字节流。
成功返回1,失败返回0。
int MD5_Final(unsigned char *md, MD5_CTX *c);
生成最终的MD5摘要串。
成功返回1,失败返回0。
unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
对于短的字符串,可以使用该函数一次性生成MD5摘要,简化调用。
使用举例:
下面这个例子演示了使用两种方式生成MD5摘要,并对比结果。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <openssl/md5.h>
namespace dakuang {}
void printHex(const unsigned char* pBuf, int nLen)
{
for (int i = 0; i < nLen; ++i)
{
printf("%02x", pBuf[i]);
}
printf("\n");
}
int main(int argc, char* argv[])
{
char sText[] = "abdefg1234567890";
{
MD5_CTX ctx;
MD5_Init(&ctx);
for (int i = 0; i < strlen(sText); ++i)
{
MD5_Update(&ctx, (void*)&sText[i], 1);
}
unsigned char sMD5[16] = {0};
int ret = MD5_Final(sMD5, &ctx);
printf("ret:%d \n", ret);
printHex(sMD5, 16);
}
{
unsigned char sMD5[16] = {0};
unsigned char* ret = MD5((const unsigned char*)sText, strlen(sText), sMD5);
printf("ret %p \n", ret);
printf("SMD5 %p \n", sMD5);
printHex(sMD5, 16);
}
return 0;
}
输出:
ret:1
e380e88e8d09ebf8d8659a15b0ea70b5
ret 0x7fff90096b20
SMD5 0x7fff90096b20
e380e88e8d09ebf8d8659a15b0ea70b5