MD5是个hash算法,具体的内容我也不想多说,其实我也没有仔细看到底4轮64次变换是怎么一回事。可以参考一下百度百科的md5词条。(http://baike.baidu.com/view/7636.htm?fr=ala0_1),我感觉比中文版的wiki写得详细点。另外子清行的《MD5算法实现注意点》这篇文章也很不错,说实话要学习这个算法真的是要自己写一遍为好。真要仔细研究的话,就看rfc1321.txt,这个最权威了。
当然,我的角度略有不同,我只是要用md5,调试或者静态分析的时候能看出来md5,所以只要知道个大概就可以了。
首先,md5算法,有个4个32位的Chaining Variable,一般叫做ABCD,这4个值分别是:
0x67452301;
0xefcdab89;
0x98badcfe;
0x10325476;
这几个数放到内存中其实很整齐,就是01234567 89ABCDEF FEDCBA98 76543210,看到这4个数,基本上就能确定有md5。
然后md5的输入是64个bytes一组的,尾部要补8bytes的bits数,数据和8bytes之间补80 00 * n。每一次变换,ABCD都被更新,最后的输出是16bytes,就是ABCD的值。
下面说下怎么用,md5现成的代码,首先考虑rfc1321.txt后面附带的代码,只要依次复制出来就可以,但是必须要用C的编译器来编译,用C++编译通不过,语法比较老。除了这个,就是md5-opt,作者是J. Touch(http://www.isi.edu/atomic2/security/md5-opts.html),性能有了优化,我是在Google Desktop的license页中看到这个东西的,其实性能问题对于小程序来说关系不大。
最后说下openssl,这个库里面有md5。用code:blocks的朋友建议装一下该库的devpak,虽然devpak很久没有更新了,openssl-devpak的最高版本是0.98e,而openssl目前已经到了1.00a,不过能用就行了。只要#include <openssl/md5.h>,另外还要连上libcrypto.a,注意不是libssl。这种大陆的算法,很多库里面都有,这个就不一一说了。
下面说下用法,一般来说就这么三个函数:
MD5Init,MD5Update和MDFinal,
还有一个变量
MD5_CTX (md5 context)
名字可能略有不同,但作用都差不多。
首先MD5Init用来初始化MD5_CTX,这个初始化一般的操作就2个,一个是ABCD赋初值,另一个是计数清零。
然后是MD5Update,这个函数的作用就是将要进行MD5的数据写入buffer,满64个就变换一次。这个函数往往会调用多次。可以想象一个大文件要进行md5,1k1k的读入,进行MD5Update,直到文件读取完毕。
最后就是MD5Final了,它的工作就是填充80 00和最后的8bytes的bits数,再变换一次,并且输出最终结果。
上面说的就是大概,我看了下md5-opt和openssl-md5,里面具体的细节真是相差很多。不过只要是标准的使用md5应该关系不大。我正好碰到的就是不怎么标准的使用md5、中途乱改md5_ctx的情况。