«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告

本站技术贴除标明为“原创”的之外,其余均为网上转载,文中我会尽量保留原作者姓名,若有侵权请与我联系,我将第一时间做出修改。谢谢!

             ——既瑜


天气预报(南京)


我的分类(专题)

首页(183)
【趣味文摘】(22)
【五子连珠】(13)
【技术文档】(136)
【电脑技术】(6)
【疑难问题】(1)
【我的心情】(5)


最新日志
花语(中英文对照版)
各种花的花语
NTFS格式的7个精彩问答(pconli
童言无忌,有趣得一蹋
给MM修电脑的三个步骤[转载]
J2EE 面试题综合
JAVA编程规则
[转] P2P之UDP穿透NAT的原理与
[转]词法分析器
文件加密技术
一个让人发狂的PI求解C程序
[转]直线生成算法之DDA
[转]利用内核对象----互斥量实现应用
[转]如何正确的计算文件收发进度
双机调试VC程序
[转]分治法优化大整数乘法 C++实现
浮点数值的内存结构
[转]双链表实现大整数的加法与乘法[VC
拜占廷将军问题[转]
某人的挂QQ的程序源代码,虽然没用了,拿

最新回复
回复:vc中的CString的操作
回复:[转]分治法优化大整数乘法 C++
回复:[转]分治法优化大整数乘法 C++
回复:花语(中英文对照版)
回复:基本排序算法比较与选择[转载]
回复:c++中强制类型转换操作符小结
回复:c++中强制类型转换操作符小结
何必那么执着于是大头猫还是愤怒的小鸟,淡
回复:浮点数值的内存结构
回复:花语(中英文对照版)
回复:花语(中英文对照版)
回复:花语(中英文对照版)
回复:花语(中英文对照版)
回复:花语(中英文对照版)
回复:32位位图到24位位图的转换
dren, ages 16 and 20
回复:花语(中英文对照版)
回复:花语(中英文对照版)
回复:花语(中英文对照版)
回复:各种花的花语

留言板
签写新留言

不是0-1背包喔
桂花的花语``
谢谢
提议
提议

统计
blog名称:★既瑜★
日志总数:183
评论数量:636
留言数量:-25
访问次数:1406010
建立时间:2005年3月12日

链接


http://www.nju.edu.cn
http://bbs.nju.edu.cn 
http://www.t7-online.com
http://www.csdn.net
http://www.91f.net
http://www.crsky.com
我的MSN BLOG 

联系我

  OICQ:215768265
  njucs2001@hotmail.com
  erichoo1982@gmail.com

 

W3CHINA Blog首页    管理页面    写新日志    退出


[【技术文档】][转载]使用md5校验和算法保护文件
既瑜(224499) 发表于 2005/8/23 22:49:16

一、理论部分:1、预备知识1.1什么是数据校验通俗的说,就是为保证数据的完整性,用一种指定的算法对原始数据计算出的一个校验值。接收方用同样的算法计算一次校验值,如果和随数据提供的校验值一样,就说明数据是完整的。1.2最简单的检验实现方法:最简单的校验就是把原始数据和待比较数据直接进行比较,看是否完全一样这种方法是最安全最准确的。同时也是效率最低的。适用范围:简单的数据量极小的通讯。应用例子:龙珠cpu在线调试工具bbug.exe。它和龙珠cpu间通讯时,bbug发送一个字节cpu返回收到的字节,bbug确认是刚才发送字节后才继续发送下一个字节的。1.3奇偶校验Parity Check实现方法:在数据存储和传输中,字节中额外增加一个比特位,用来检验错误。校验位可以通过数据位异或计算出来。应用例子:单片机串口通讯有一模式就是8位数据通讯,另加第9位用于放校验值。1.4 bcc异或校验法(block check character)实现方法:很多基于串口的通讯都用这种既简单又相当准确的方法。它就是把所有数据都和一个指定的初始值(通常是0)异或一次,最后的结果就是校验值,通常把她附在通讯数据的最后一起发送出去。接收方收到数据后自己也计算一次异或和校验值,如果和收到的校验值一致就说明收到的数据是完整的。校验值计算的代码类似于:unsigned uCRC=0;//校验初始值for(int i=0;i<DataLenth;i++) uCRC^=Data[i];适用范围:适用于大多数要求不高的数据通讯。应用例子:ic卡接口通讯、很多单片机系统的串口通讯都使用。1.5 crc循环冗余校验(Cyclic Redundancy Check)实现方法:这是利用除法及余数的原理来进行错误检测的.将接收到的码组进行除法运算,如果除尽,则说明传输无误;如果未除尽,则表明传输出现差错。crc校验具还有自动纠错能力。crc检验主要有计算法和查表法两种方法,网上很多实现代码。 适用范围:CRC-12码通常用来传送6-bit字符串;CRC-16及CRC-CCITT码则用是来传送8-bit字符。CRC-32:硬盘数据,网络传输等应用例子:rar,以太网卡芯片、MPEG解码芯片中1.6 md5校验和数字签名实现方法:主要有md5和des算法。适用范围:数据比较大或要求比较高的场合。如md5用于大量数据、文件校验,des用于保密数据的校验(数字签名)等等。应用例子:文件校验、银行系统的交易数据 2、具体的实现理论2.1 算法概述MD5算法是MD4算法的改进算法。Ron Rivest 于1990年提出MD4单向散列函数,MD表示消息摘要(Message Digest),对输入消息,算法产生128位散列值。该算法首次公布之后,Bert den Boer和Antoon Bosselaers 对算法三轮中的后两轮进行了成功的密码分析。在一个不相关的分析结果中,Ralph MerKle成功地攻击了前两轮。尽管这些攻击都没有扩展到整个算法,但Rivest还是改进了其算法,结果就是MD5算法。 MD5算法是MD4的改进算法,它比MD4更复杂,但设计思想相似,输入的消息可任意长,输出结果也仍为128位,特别适用于高速软件实现,是基于32-位操作数的一些简单的位操作。2.2 算法步骤l 将输入消息按512-位分组,最后要填充成为512位的整数倍,且最后一组的后64位用来填充消息长度(填充前)。填充方法为附一个1在消息后,后接所要求的多个0。这样可以确保不同消息在填充后不相同。l 由于留出64位用来表示消息长度,那么消息的长度最多可达264字节,相当于4G×4G字节,文件的长度是不可能达到这么大,因此通常都是只采用64位中的低32位来表示消息长度,高32位填充0。l 初始化MD变量。由于每轮输出128位,这128位可用下面四个32位字A,B,C,D来表示。其初始值设为:A=0x01234567B=0x89ABCDEFC=0xFEDCBA98D=0x76543210l 开始进入算法主循环,循环的次数是消息中512位消息分组的数目。先将上面A、B、C、D四个变量分别复制到另外四个变量a、b、c、d中去。主循环有四轮,每轮很相似。每轮进行16次操作,每次操作对a、b、c、d四个变量中的三个作一次非线性函数运算,然后将所得结果加上第四个变量,消息的一个子分组和一个常数。再将所得结果向右环移一个不定的数,并加上a,b,c或d中之一。最后用该结果取代a,b,c或d中之一。以下是每次操作中用到的四个非线性函数(每轮一个)。F(X,Y,Z)=(X∧Y)∨(( X)∧Z)G(X,Y,Z)=(X∧Z)∨(Y∧( Z))H(X,Y,Z)=X⊕Y⊕ZI(X,Y,Z)=Y⊕(X∨( Z))其中,⊕是异或,∧是与,∨是或, 是反符号。这些函数是这样设计的:如果X、Y和Z的对应位是独立和均匀的,那么结果的每一位也应是独立和均匀的。函数F是按逐位方式操作:如果X,那么Y,否则Z。函数H是逐位奇偶操作符。设Mj表示消息的第j个子分组(从0到15),<<<s表示循环左移s,则四种操作为:FF(a,b,c,d,Mj,s,ti)表示a = b+((a+F(b,c,d)+ Mj + ti)<<<s)GG(a,b,c,d,Mj,s,ti)表示a = b+((a+G(b,c,d)+ Mj + ti)<<<s)HH(a,b,c,d,Mj,s,ti)表示a = b+((a+H(b,c,d)+ Mj + ti)<<<s)II(a,b,c,d,Mj,s,ti)表示a = b+((a+I(b,c,d)+ Mj + ti)<<<s)四轮(64步)结果略。注:常数ti的选择:第i步中,ti是232 ×abs (sin(i))的整数部分,i的单位是弧度。所有这些完成之后,将A,B,C,D分别加上a,b,c,d。然后用下一分组数据继续运行算法,最后的输出是A,B,C和D的级联。l 最后得到的A,B,C,D就是输出结果,A是低位,D为高位,DCBA组成128位输出结果。2.3 MD5的安全性Ron Rivest概述了MD5安全性[8]:l 与MD4相比,增加了第四轮。l 每一步均有唯一的加法常数。l 为减弱第二轮中函数G的对称性从((X∧Y) ∨(X∧Z) ∨(Y∧Z))变为((X∧Z) ∨(Y∧( Z)))。l 每一步加上了上一步的结果,引起更快的雪崩效应。l 改变了第二轮和第三轮中访问消息子分组的次序,使其形式更不相似。l 近似优化了每一轮中的循环左移位移量以实现更快的雪崩效应。各轮的位移量互不相同。从安全角度讲,MD5的输出为128位,若采用纯强力攻击寻找一个消息具有给定Hash值的计算困难性为2128,用每秒可试验1 000 000 000个消息的计算机需时1.07×1022年。若采用生日攻击法,寻找有相同Hash值的两个消息需要试验264个消息,用每秒可试验1 000 000 000个消息的计算机需时585年。 二、实现方法 由于此处的文件校验用到要求比较高的场合,故采用了方法6,md5校验算法,从CodeGuru下载了一个md5校验算法的实现模块,加入自己要校验的文件名,实现完成。下面具体描述一下实现过程:1、创建一个简单的对话框程序;2、设置CString类型的变量m_filename和m_strFileChecksum以存放要校验的文件名和校验和;3、在对话框类中创建ChecksumSelectedFile()函数,调用md5校验和类(附录中有其实现文件)中的GetMD5计算文件校验和。4、使用定时器定时巡检该文件的校验和,一旦发现校验和发生变化,立刻出现提示。三、附录(md5算法实现的源码)以下代码实现均来自www.codeguru.com。1、MD5ChecksumDefines.h(定义相关常量的头文件)//Magic initialization constants#define MD5_INIT_STATE_0 0x67452301#define MD5_INIT_STATE_1 0xefcdab89#define MD5_INIT_STATE_2 0x98badcfe#define MD5_INIT_STATE_3 0x10325476 //Constants for Transform routine.#define MD5_S11  7#define MD5_S12 12#define MD5_S13 17#define MD5_S14 22#define MD5_S21  5#define MD5_S22  9#define MD5_S23 14#define MD5_S24 20#define MD5_S31  4#define MD5_S32 11#define MD5_S33 16#define MD5_S34 23#define MD5_S41  6#define MD5_S42 10#define MD5_S43 15#define MD5_S44 21 //Transformation Constants - Round 1#define MD5_T01  0xd76aa478 //Transformation Constant 1 #define MD5_T02  0xe8c7b756 //Transformation Constant 2#define MD5_T03  0x242070db //Transformation Constant 3#define MD5_T04  0xc1bdceee //Transformation Constant 4#define MD5_T05  0xf57c0faf //Transformation Constant 5#define MD5_T06  0x4787c62a //Transformation Constant 6#define MD5_T07  0xa8304613 //Transformation Constant 7#define MD5_T08  0xfd469501 //Transformation Constant 8#define MD5_T09  0x698098d8 //Transformation Constant 9#define MD5_T10  0x8b44f7af //Transformation Constant 10#define MD5_T11  0xffff5bb1 //Transformation Constant 11#define MD5_T12  0x895cd7be //Transformation Constant 12#define MD5_T13  0x6b901122 //Transformation Constant 13#define MD5_T14  0xfd987193 //Transformation Constant 14#define MD5_T15  0xa679438e //Transformation Constant 15#define MD5_T16  0x49b40821 //Transformation Constant 16 //Transformation Constants - Round 2#define MD5_T17  0xf61e2562 //Transformation Constant 17#define MD5_T18  0xc040b340 //Transformation Constant 18#define MD5_T19  0x265e5a51 //Transformation Constant 19#define MD5_T20  0xe9b6c7aa //Transformation Constant 20#define MD5_T21  0xd62f105d //Transformation Constant 21#define MD5_T22  0x02441453 //Transformation Constant 22#define MD5_T23  0xd8a1e681 //Transformation Constant 23#define MD5_T24  0xe7d3fbc8 //Transformation Constant 24#define MD5_T25  0x21e1cde6 //Transformation Constant 25#define MD5_T26  0xc33707d6 //Transformation Constant 26#define MD5_T27  0xf4d50d87 //Transformation Constant 27#define MD5_T28  0x455a14ed //Transformation Constant 28#define MD5_T29  0xa9e3e905 //Transformation Constant 29#define MD5_T30  0xfcefa3f8 //Transformation Constant 30#define MD5_T31  0x676f02d9 //Transformation Constant 31#define MD5_T32  0x8d2a4c8a //Transformation Constant 32 //Transformation Constants - Round 3#define MD5_T33  0xfffa3942 //Transformation Constant 33#define MD5_T34  0x8771f681 //Transformation Constant 34#define MD5_T35  0x6d9d6122 //Transformation Constant 35#define MD5_T36  0xfde5380c //Transformation Constant 36#define MD5_T37  0xa4beea44 //Transformation Constant 37#define MD5_T38  0x4bdecfa9 //Transformation Constant 38#define MD5_T39  0xf6bb4b60 //Transformation Constant 39#define MD5_T40  0xbebfbc70 //Transformation Constant 40#define MD5_T41  0x289b7ec6 //Transformation Constant 41#define MD5_T42  0xeaa127fa //Transformation Constant 42#define MD5_T43  0xd4ef3085 //Transformation Constant 43#define MD5_T44  0x04881d05 //Transformation Constant 44#define MD5_T45  0xd9d4d039 //Transformation Constant 45#define MD5_T46  0xe6db99e5 //Transformation Constant 46#define MD5_T47  0x1fa27cf8 //Transformation Constant 47#define MD5_T48  0xc4ac5665 //Transformation Constant 48 //Transformation Constants - Round 4#define MD5_T49  0xf4292244 //Transformation Constant 49#define MD5_T50  0x432aff97 //Transformation Constant 50#define MD5_T51  0xab9423a7 //Transformation Constant 51#define MD5_T52  0xfc93a039 //Transformation Constant 52#define MD5_T53  0x655b59c3 //Transformation Constant 53#define MD5_T54  0x8f0ccc92 //Transformation Constant 54#define MD5_T55  0xffeff47d //Transformation Constant 55#define MD5_T56  0x85845dd1 //Transformation Constant 56#define MD5_T57  0x6fa87e4f //Transformation Constant 57#define MD5_T58  0xfe2ce6e0 //Transformation Constant 58#define MD5_T59  0xa3014314 //Transformation Constant 59#define MD5_T60  0x4e0811a1 //Transformation Constant 60#define MD5_T61  0xf7537e82 //Transformation Constant 61#define MD5_T62  0xbd3af235 //Transformation Constant 62#define MD5_T63  0x2ad7d2bb //Transformation Constant 63#define MD5_T64  0xeb86d391 //Transformation Constant 64 //Null data (except for first BYTE) used to finalise the checksum calculationstatic 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};2、CountChecksum.h(md5校验和类的头文件)class CMD5Checksum  {public: //interface functions for the RSA MD5 calculation static CString GetMD5(BYTE* pBuf, UINT nLength); static CString GetMD5(CFile& File); static CString GetMD5(const CString& strFilePath); protected: //constructor/destructor CMD5Checksum(); virtual ~CMD5Checksum() {};  //RSA MD5 implementation void Transform(BYTE Block[64]); void Update(BYTE* Input, ULONG nInputLen); CString Final(); inline DWORD RotateLeft(DWORD x, int n); inline void FF( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T); inline void GG( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T); inline void HH( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T); inline void II( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T);  //utility functions void DWordToByte(BYTE* Output, DWORD* Input, UINT nLength); void ByteToDWord(DWORD* Output, BYTE* Input, UINT nLength); private: BYTE  m_lpszBuffer[64];  //input buffer ULONG m_nCount[2];   //number of bits, modulo 2^64 (lsb first) ULONG m_lMD5[4];   //MD5 checksum}; #endif // !defined(AFX_MD5CHECKSUM_H__2BC7928E_4C15_11D3_B2EE_A4A60E20D2C3__INCLUDED_)3、CountChecksum.cpp (md5校验和类的实现文件)/*****************************************************************************************FUNCTION:  CMD5Checksum::GetMD5DETAILS:  static, publicDESCRIPTION: Gets the MD5 checksum for a specified fileRETURNS:  CString : the hexadecimal MD5 checksum for the specified fileARGUMENTS:  CString& strFilePath : the full pathname of the specified fileNOTES:   Provides an interface to the CMD5Checksum class. 'strFilePath' name should     hold the full pathname of the file, eg C:\My Documents\Arcticle.txt.    NB. If any problems occur with opening or reading this file, a CFileException    will be thrown; callers of this function should be ready to catch this     exception.*****************************************************************************************/CString CMD5Checksum::GetMD5(const CString& strFilePath){ //open the file as a binary file in readonly mode, denying write access  CFile File(strFilePath, CFile::shareDenyNone); //the file has been successfully opened, so now get and return its checksum return GetMD5(File);} /*****************************************************************************************FUNCTION:  CMD5Checksum::GetMD5DETAILS:  static, publicDESCRIPTION: Gets the MD5 checksum for a specified fileRETURNS:  CString : the hexadecimal MD5 checksum for the specified fileARGUMENTS:  CFile& File : the specified fileNOTES:   Provides an interface to the CMD5Checksum class. 'File' should be open in     binary readonly mode before calling this function.     NB. Callers of this function should be ready to catch any CFileException    thrown by the CFile functions*****************************************************************************************/CString CMD5Checksum::GetMD5(CFile& File){ try {  CMD5Checksum MD5Checksum;  //checksum object   int nLength = 0;    //number of bytes read from the file  const int nBufferSize = 1024; //checksum the file in blocks of 1024 bytes  BYTE Buffer[nBufferSize];  //buffer for data read from the file   //checksum the file in blocks of 1024 bytes  while ((nLength = File.Read( Buffer, nBufferSize )) > 0 )  {   MD5Checksum.Update( Buffer, nLength );  }   //finalise the checksum and return it  return MD5Checksum.Final(); }  //report any file exceptions in debug mode only catch (CFileException* e ) {  TRACE0("CMD5Checksum::GetMD5: CFileException caught");   throw e; }} /*****************************************************************************************FUNCTION:  CMD5Checksum::GetMD5DETAILS:  static, publicDESCRIPTION: Gets the MD5 checksum for data in a BYTE arrayRETURNS:  CString : the hexadecimal MD5 checksum for the specified dataARGUMENTS:  BYTE* pBuf  : pointer to the BYTE array    UINT nLength : number of BYTEs of data to be checksumedNOTES:   Provides an interface to the CMD5Checksum class. Any data that can    be cast to a BYTE array of known length can be checksummed by this    function. Typically, CString and char arrays will be checksumed,     although this function can be used to check the integrity of any BYTE array.     A buffer of zero length can be checksummed; all buffers of zero length     will return the same checksum. *****************************************************************************************/CString CMD5Checksum::GetMD5(BYTE* pBuf, UINT nLength){ //entry invariants AfxIsValidAddress(pBuf,nLength,FALSE);  //calculate and return the checksum CMD5Checksum MD5Checksum; MD5Checksum.Update( pBuf, nLength ); return MD5Checksum.Final();} /*****************************************************************************************FUNCTION:  CMD5Checksum::RotateLeftDETAILS:  privateDESCRIPTION: Rotates the bits in a 32 bit DWORD left by a specified amountRETURNS:  The rotated DWORD ARGUMENTS:  DWORD x : the value to be rotated    int n   : the number of bits to rotate by*****************************************************************************************/DWORD CMD5Checksum::RotateLeft(DWORD x, int n){ //check that DWORD is 4 bytes long - true in Visual C++ 6 and 32 bit Windows ASSERT( sizeof(x) == 4 );  //rotate and return x return (x << n) | (x >> (32-n));} /*****************************************************************************************FUNCTION:  CMD5Checksum::FFDETAILS:  protectedDESCRIPTION: Implementation of basic MD5 transformation algorithmRETURNS:  noneARGUMENTS:  DWORD &A, B, C, D : Current (partial) checksum    DWORD X           : Input data    DWORD S     : MD5_SXX Transformation constant    DWORD T     : MD5_TXX Transformation constantNOTES:   None*****************************************************************************************/void CMD5Checksum::FF( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T){ DWORD F = (B & C) | (~B & D); A += F + X + T; A = RotateLeft(A, S); A += B;} /*****************************************************************************************FUNCTION:  CMD5Checksum::GGDETAILS:  protectedDESCRIPTION: Implementation of basic MD5 transformation algorithmRETURNS:  noneARGUMENTS:  DWORD &A, B, C, D : Current (partial) checksum    DWORD X           : Input data    DWORD S     : MD5_SXX Transformation constant    DWORD T     : MD5_TXX Transformation constantNOTES:   None*****************************************************************************************/void CMD5Checksum::GG( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T){ DWORD G = (B & D) | (C & ~D); A += G + X + T; A = RotateLeft(A, S); A += B;} /*****************************************************************************************FUNCTION:  CMD5Checksum::HHDETAILS:  protectedDESCRIPTION: Implementation of basic MD5 transformation algorithmRETURNS:  noneARGUMENTS:  DWORD &A, B, C, D : Current (partial) checksum    DWORD X           : Input data    DWORD S     : MD5_SXX Transformation constant    DWORD T     : MD5_TXX Transformation constantNOTES:   None*****************************************************************************************/void CMD5Checksum::HH( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T){ DWORD H = (B ^ C ^ D); A += H + X + T; A = RotateLeft(A, S); A += B;} /*****************************************************************************************FUNCTION:  CMD5Checksum::IIDETAILS:  protectedDESCRIPTION: Implementation of basic MD5 transformation algorithmRETURNS:  noneARGUMENTS:  DWORD &A, B, C, D : Current (partial) checksum    DWORD X           : Input data    DWORD S     : MD5_SXX Transformation constant    DWORD T     : MD5_TXX Transformation constantNOTES:   None*****************************************************************************************/void CMD5Checksum::II( DWORD& A, DWORD B, DWORD C, DWORD D, DWORD X, DWORD S, DWORD T){ DWORD I = (C ^ (B | ~D)); A += I + X + T; A = RotateLeft(A, S); A += B;} /*****************************************************************************************FUNCTION:  CMD5Checksum::ByteToDWordDETAILS:  privateDESCRIPTION: Transfers the data in an 8 bit array to a 32 bit arrayRETURNS:  voidARGUMENTS:  DWORD* Output : the 32 bit (unsigned long) destination array     BYTE* Input   : the 8 bit (unsigned char) source array    UINT nLength  : the number of 8 bit data items in the source arrayNOTES:   Four BYTES from the input array are transferred to each DWORD entry    of the output array. The first BYTE is transferred to the bits (0-7)     of the output DWORD, the second BYTE to bits 8-15 etc.     The algorithm assumes that the input array is a multiple of 4 bytes long    so that there is a perfect fit into the array of 32 bit words.*****************************************************************************************/void CMD5Checksum::ByteToDWord(DWORD* Output, BYTE* Input, UINT nLength){ //entry invariants ASSERT( nLength % 4 == 0 ); ASSERT( AfxIsValidAddress(Output, nLength/4, TRUE) ); ASSERT( AfxIsValidAddress(Input, nLength, FALSE) );  //initialisations UINT i=0; //index to Output array UINT j=0; //index to Input array  //transfer the data by shifting and copying for ( ; j < nLength; i++, j += 4) {  Output[i] = (ULONG)Input[j]   |      (ULONG)Input[j+1] << 8 |      (ULONG)Input[j+2] << 16 |      (ULONG)Input[j+3] << 24; }} /*****************************************************************************************FUNCTION:  CMD5Checksum::TransformDETAILS:  protectedDESCRIPTION: MD5 basic transformation algorithm;  transforms 'm_lMD5'RETURNS:  voidARGUMENTS:  BYTE Block[64]NOTES:   An MD5 checksum is calculated by four rounds of 'Transformation'.    The MD5 checksum currently held in m_lMD5 is merged by the     transformation process with data passed in 'Block'.  *****************************************************************************************/void CMD5Checksum::Transform(BYTE Block[64]){ //initialise local data with current checksum ULONG a = m_lMD5[0]; ULONG b = m_lMD5[1]; ULONG c = m_lMD5[2]; ULONG d = m_lMD5[3];  //copy BYTES from input 'Block' to an array of ULONGS 'X' ULONG X[16]; ByteToDWord( X, Block, 64 );  //Perform Round 1 of the transformation FF (a, b, c, d, X[ 0], MD5_S11, MD5_T01);  FF (d, a, b, c, X[ 1], MD5_S12, MD5_T02);  FF (c, d, a, b, X[ 2], MD5_S13, MD5_T03);  FF (b, c, d, a, X[ 3], MD5_S14, MD5_T04);  FF (a, b, c, d, X[ 4], MD5_S11, MD5_T05);  FF (d, a, b, c, X[ 5], MD5_S12, MD5_T06);  FF (c, d, a, b, X[ 6], MD5_S13, MD5_T07);  FF (b, c, d, a, X[ 7], MD5_S14, MD5_T08);  FF (a, b, c, d, X[ 8], MD5_S11, MD5_T09);  FF (d, a, b, c, X[ 9], MD5_S12, MD5_T10);  FF (c, d, a, b, X[10], MD5_S13, MD5_T11);  FF (b, c, d, a, X[11], MD5_S14, MD5_T12);  FF (a, b, c, d, X[12], MD5_S11, MD5_T13);  FF (d, a, b, c, X[13], MD5_S12, MD5_T14);  FF (c, d, a, b, X[14], MD5_S13, MD5_T15);  FF (b, c, d, a, X[15], MD5_S14, MD5_T16);  //Perform Round 2 of the transformation GG (a, b, c, d, X[ 1], MD5_S21, MD5_T17);  GG (d, a, b, c, X[ 6], MD5_S22, MD5_T18);  GG (c, d, a, b, X[11], MD5_S23, MD5_T19);  GG (b, c, d, a, X[ 0], MD5_S24, MD5_T20);  GG (a, b, c, d, X[ 5], MD5_S21, MD5_T21);  GG (d, a, b, c, X[10], MD5_S22, MD5_T22);  GG (c, d, a, b, X[15], MD5_S23, MD5_T23);  GG (b, c, d, a, X[ 4], MD5_S24, MD5_T24);  GG (a, b, c, d, X[ 9], MD5_S21, MD5_T25);  GG (d, a, b, c, X[14], MD5_S22, MD5_T26);  GG (c, d, a, b, X[ 3], MD5_S23, MD5_T27);  GG (b, c, d, a, X[ 8], MD5_S24, MD5_T28);  GG (a, b, c, d, X[13], MD5_S21, MD5_T29);  GG (d, a, b, c, X[ 2], MD5_S22, MD5_T30);  GG (c, d, a, b, X[ 7], MD5_S23, MD5_T31);  GG (b, c, d, a, X[12], MD5_S24, MD5_T32);  //Perform Round 3 of the transformation HH (a, b, c, d, X[ 5], MD5_S31, MD5_T33);  HH (d, a, b, c, X[ 8], MD5_S32, MD5_T34);  HH (c, d, a, b, X[11], MD5_S33, MD5_T35);  HH (b, c, d, a, X[14], MD5_S34, MD5_T36);  HH (a, b, c, d, X[ 1], MD5_S31, MD5_T37);  HH (d, a, b, c, X[ 4], MD5_S32, MD5_T38);  HH (c, d, a, b, X[ 7], MD5_S33, MD5_T39);  HH (b, c, d, a, X[10], MD5_S34, MD5_T40);  HH (a, b, c, d, X[13], MD5_S31, MD5_T41);  HH (d, a, b, c, X[ 0], MD5_S32, MD5_T42);  HH (c, d, a, b, X[ 3], MD5_S33, MD5_T43);  HH (b, c, d, a, X[ 6], MD5_S34, MD5_T44);  HH (a, b, c, d, X[ 9], MD5_S31, MD5_T45);  HH (d, a, b, c, X[12], MD5_S32, MD5_T46);  HH (c, d, a, b, X[15], MD5_S33, MD5_T47);  HH (b, c, d, a, X[ 2], MD5_S34, MD5_T48);  //Perform Round 4 of the transformation II (a, b, c, d, X[ 0], MD5_S41, MD5_T49);  II (d, a, b, c, X[ 7], MD5_S42, MD5_T50);  II (c, d, a, b, X[14], MD5_S43, MD5_T51);  II (b, c, d, a, X[ 5], MD5_S44, MD5_T52);  II (a, b, c, d, X[12], MD5_S41, MD5_T53);  II (d, a, b, c, X[ 3], MD5_S42, MD5_T54);  II (c, d, a, b, X[10], MD5_S43, MD5_T55);  II (b, c, d, a, X[ 1], MD5_S44, MD5_T56);  II (a, b, c, d, X[ 8], MD5_S41, MD5_T57);  II (d, a, b, c, X[15], MD5_S42, MD5_T58);  II (c, d, a, b, X[ 6], MD5_S43, MD5_T59);  II (b, c, d, a, X[13], MD5_S44, MD5_T60);  II (a, b, c, d, X[ 4], MD5_S41, MD5_T61);  II (d, a, b, c, X[11], MD5_S42, MD5_T62);  II (c, d, a, b, X[ 2], MD5_S43, MD5_T63);  II (b, c, d, a, X[ 9], MD5_S44, MD5_T64);  //add the transformed values to the current checksum m_lMD5[0] += a; m_lMD5[1] += b; m_lMD5[2] += c; m_lMD5[3] += d;} /*****************************************************************************************CONSTRUCTOR: CMD5ChecksumDESCRIPTION: Initialises member dataARGUMENTS:  NoneNOTES:   None*****************************************************************************************/CMD5Checksum::CMD5Checksum(){ // zero members memset( m_lpszBuffer, 0, 64 ); m_nCount[0] = m_nCount[1] = 0;  // Load magic state initialization constants m_lMD5[0] = MD5_INIT_STATE_0; m_lMD5[1] = MD5_INIT_STATE_1; m_lMD5[2] = MD5_INIT_STATE_2; m_lMD5[3] = MD5_INIT_STATE_3;} /*****************************************************************************************FUNCTION:  CMD5Checksum::DWordToByteDETAILS:  privateDESCRIPTION: Transfers the data in an 32 bit array to a 8 bit arrayRETURNS:  voidARGUMENTS:  BYTE* Output  : the 8 bit destination array     DWORD* Input  : the 32 bit source array    UINT nLength  : the number of 8 bit data items in the source arrayNOTES:   One DWORD from the input array is transferred into four BYTES     in the output array. The first (0-7) bits of the first DWORD are     transferred to the first output BYTE, bits bits 8-15 are transferred from    the second BYTE etc.         The algorithm assumes that the output array is a multiple of 4 bytes long    so that there is a perfect fit of 8 bit BYTES into the 32 bit DWORDs.*****************************************************************************************/void CMD5Checksum::DWordToByte(BYTE* Output, DWORD* Input, UINT nLength ){ //entry invariants ASSERT( nLength % 4 == 0 ); ASSERT( AfxIsValidAddress(Output, nLength, TRUE) ); ASSERT( AfxIsValidAddress(Input, nLength/4, FALSE) );  //transfer the data by shifting and copying UINT i = 0; UINT j = 0; for ( ; j < nLength; i++, j += 4)  {  Output[j] =   (UCHAR)(Input[i] & 0xff);  Output[j+1] = (UCHAR)((Input[i] >> 8) & 0xff);  Output[j+2] = (UCHAR)((Input[i] >> 16) & 0xff);  Output[j+3] = (UCHAR)((Input[i] >> 24) & 0xff); }} /*****************************************************************************************FUNCTION:  CMD5Checksum::FinalDETAILS:  protectedDESCRIPTION: Implementation of main MD5 checksum algorithm; ends the checksum calculation.RETURNS:  CString : the final hexadecimal MD5 checksum result ARGUMENTS:  NoneNOTES:   Performs the final MD5 checksum calculation ('Update' does most of the work,    this function just finishes the calculation.) *****************************************************************************************/CString CMD5Checksum::Final(){ //Save number of bits BYTE Bits[8]; DWordToByte( Bits, m_nCount, 8 );  //Pad out to 56 mod 64. UINT nIndex = (UINT)((m_nCount[0] >> 3) & 0x3f); UINT nPadLen = (nIndex < 56) ? (56 - nIndex) : (120 - nIndex); Update( PADDING, nPadLen );  //Append length (before padding) Update( Bits, 8 );  //Store final state in 'lpszMD5' const int nMD5Size = 16; unsigned char lpszMD5[ nMD5Size ]; DWordToByte( lpszMD5, m_lMD5, nMD5Size );  //Convert the hexadecimal checksum to a CString CString strMD5; for ( int i=0; i < nMD5Size; i++)  {  CString Str;  if (lpszMD5[i] == 0) {   Str = CString("00");  }  else if (lpszMD5[i] <= 15)  {   Str.Format("0%x",lpszMD5[i]);  }  else {   Str.Format("%x",lpszMD5[i]);  }   ASSERT( Str.GetLength() == 2 );  strMD5 += Str; } ASSERT( strMD5.GetLength() == 32 ); return strMD5;} /*****************************************************************************************FUNCTION:  CMD5Checksum::UpdateDETAILS:  protectedDESCRIPTION: Implementation of main MD5 checksum algorithmRETURNS:  voidARGUMENTS:  BYTE* Input    : input block    UINT nInputLen : length of input blockNOTES:   Computes the partial MD5 checksum for 'nInputLen' bytes of data in 'Input'*****************************************************************************************/void CMD5Checksum::Update( BYTE* Input, ULONG nInputLen ){ //Compute number of bytes mod 64 UINT nIndex = (UINT)((m_nCount[0] >> 3) & 0x3F);  //Update number of bits if ( ( m_nCount[0] += nInputLen << 3 )  <  ( nInputLen << 3) ) {  m_nCount[1]++; } m_nCount[1] += (nInputLen >> 29);  //Transform as many times as possible. UINT i=0;   UINT nPartLen = 64 - nIndex; if (nInputLen >= nPartLen)   {  memcpy( &m_lpszBuffer[nIndex], Input, nPartLen );  Transform( m_lpszBuffer );  for (i = nPartLen; i + 63 < nInputLen; i += 64)   {   Transform( &Input[i] );  }  nIndex = 0; }  else  {  i = 0; }  // Buffer remaining input memcpy( &m_lpszBuffer[nIndex], &Input[i], nInputLen-i);}

阅读全文(3265) | 回复(2) | 编辑 | 精华

回复:[转载]使用md5校验和算法保护文件
11nong(游客)发表评论于2006/3/21 10:56:33

very good!

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除

回复:[转载]使用md5校验和算法保护文件
111(游客)发表评论于2006/1/9 15:16:20

好东西,懂了不少
个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除

» 1 »

发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)

站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.250 second(s), page refreshed 144762938 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号