MD5 算法实现
一、MD5密码保护
MD5因为它的低碰撞性,常用于数据压缩,尤其是对于密码的保护。因为它是不可逆的,明文密码加密后得到的密文无法推出原文,并且校验密码可以转为校验密码加密得到的MD5值,所以在数据库中只要存密码的MD5值,在需要校验的时候只需求出输入的MD5值并和数据库内容比较是否一致,既不泄露用户信息,又几乎不可能出错。
二、MD5算法流程
1.处理输入字符串,在整串后面补充比特位”100…000”若干(必须至少补充一个位1),并在最后再补充额外的64位来表示字符串的长度。然后将之分割成L组长度为512的子串。
2.将上述的L个512bits长度的子串分别作一系列压缩,并且每步的结果会作为下一步的输入。
3.压缩过程又分为使用4个不同的函数F, G, H, I, 每个函数又分别迭代16次,故对于每一个输入的子串,都要进行64轮迭代。
4.每一个压缩函数每轮都会输入A,B,C,D四个32位的数,这四个数还需要另外保存在长度为128的串CV中。这四个数拥有固定的初始值。变量T作为另一个输入,它与迭代的轮数有关。还有一个输入的变量是S,这个可以查表得到。至于输入的那个512位的子串,它会先被区分为16个32位的串,表示成长度16的unsigned int大小的数组,然后根据轮数i查一个名为X的表,找出对应的数作为下标,从长度为16的数组中取出对应下标的元素作为压缩函数的最后一个输入变量。
5.每一轮压缩后得到新的A,B,C,D输出,加进CV中,再以D,A,B,C的顺序作为下一轮的输入。
6.迭代最后,每一个512位的子串都会得到最终的由各轮迭代产生的A,B,C,D相加得到的128位长的CV中。这就是最终我们所需的MD5值。
三、C语言源代码
MD5.c :
MD5函数可供直接调用,传入两个指针,前者最终指向MD5值,后者则是需要压缩的字符串。
F,G,H,I函数分别为四个轮函数。
H_MD5函数为循环压缩函数。
最后main函数里测试MD5函数的运行情况。
#include <memory.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
unsigned char PADDING[] = {
128, 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
};
unsigned int F(unsigned int A, unsigned int B, unsigned int C, unsigned int D, unsigned int X, unsigned int T, unsigned int S) {
A += ((B & C) | (~B & D));
A += X + T;
A = ((A << S) | (A >> (