您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 国内外标准规范 > MD5算法简介及两种实现方法(使用WindowsAPI函数)
MD5简介MD5的全称是Message-DigestAlgorithm5(信息-摘要算法),在90年代初由MITLaboratoryforComputerScience和RSADataSecurityInc的RonaldL.Rivest开发出来,经MD2、MD3和MD4发展而来。它的作用是让大容量信息在用数字签名软件签署私人密匙前被压缩成一种保密的格式。MD5算法的描述和C语言源代码在InternetRFCs1321中有详细的描述(),这是一份最权威的文档,由RonaldL.Rivest在1992年8月向IEFT提交。我们先来看看RFC文档中对MD5的描述:ThisdocumentdescribestheMD5message-digestalgorithm(摘要).Thealgorithmtakesasinputamessageofarbitrarylength(任意长度)andproducesasoutputa128-bitfingerprintormessagedigestoftheinput.Itisconjecturedthatitiscomputationallyinfeasible(不可实行的)toproducetwomessageshavingthesamemessagedigest,ortoproduceanymessagehavingagivenprespecifiedtargetmessagedigest.TheMD5algorithmisintendedfordigitalsignatureapplications,wherealargefilemustbecompressedinasecuremannerbeforebeingencryptedwithaprivate(secret)keyunderapublic-keycryptosystemsuchasRSA.从上面的RFC描述中,可以总结出MD5摘要算法两个最重要的特性:1、不可逆,无法由结果退出输入2、twomessages不可能拥有相同的摘要信息,保证一对一正是这两个特性保证了MD5在数字签名中的应用,将一个需要签名的大文件转换为等价的128bit的摘要信息,再用私钥对128bit的摘要信息进行加密。摘要的结果是128bit的,所以网上经常看到的32位/16位MD5中的位对应的是16进制的32和16,128bit刚好是32字节。MD5只是一个摘要算法,由于它具有上面说的两个特性,在实际中(很多网站)也被用来对密码进行摘要,起到加密的作用。算法实现关于MD5的算法实现,当然可以参考RFC文档中的源代码,不过如果只在Windows平台应用的话,完全可以偷懒,调用Windows现有的API函数,只需三个API就可以搞定,很简单,呵呵!,分别是MD5Init、MD5Update、MD5Final,只是这三个函数没有在windows的.h头文件中有定义,也没有相应的importlibrary,需要自己声明它们的函数原型,这三个函数的具体实现在Cryptdll.dll中,需要动态加载!实现一:下面是具体的源代码,用Cryptdll.dll中的三个api实现:用法:MD5.exe[空格]input_message#includestdafx.h#includeWindows.h#includewindows.h#includeiostreamusingnamespacestd;typedefstruct{ULONGi[2];ULONGbuf[4];unsignedcharin[64];unsignedchardigest[16];}MD5_CTX;typedefvoid(CALLBACK*MD5Init_Tpye)(MD5_CTX*context);typedefvoid(CALLBACK*MD5Update_Tpye)(MD5_CTX*context,unsignedchar*input,unsignedintinlen);typedefvoid(CALLBACK*MD5Final_Tpye)(MD5_CTX*context);intmain(intargc,char**argv){if(argc!=2){coutargscounterr!endl;return0;}HINSTANCEhDLL=LoadLibrary(LCryptdll.dll);if(hDLL==NULL){return-1;}MD5Init_TpyeMD5Init;MD5Update_TpyeMD5Update;MD5Final_TpyeMD5Final;MD5Init=(MD5Init_Tpye)GetProcAddress(hDLL,MD5Init);MD5Update=(MD5Update_Tpye)GetProcAddress(hDLL,MD5Update);MD5Final=(MD5Final_Tpye)GetProcAddress(hDLL,MD5Final);if(MD5Init==NULL||MD5Update==NULL||MD5Final==NULL){FreeLibrary(hDLL);return-1;}MD5_CTXmd5_context;MD5Init(&md5_context);unsignedcharsrc[100];unsignedlength=strlen(argv[1]);memcpy(src,argv[1],length);MD5Update(&md5_context,src,length);MD5Final(&md5_context);chardest[100]={0};char*p=dest;for(inti=0;i16;++i){sprintf_s(p,3,%02x,md5_context.digest[i]);p+=2;}coutdestendl;FreeLibrary(hDLL);return0;}实现二:一个WinCryptoAPI封装的类Cmd5Capi,使用到了MFC中的CString类,用法:CStringinput,output;//选择一Cmd5Capimd5;output=md5.Digest(input);//选择二Cmd5Capimd5(in);out=md5.GetDigest();//////////////////////////////////////////////////////////////////////////md5Capi.h:interfacefortheCmd5Capiclass.////////////////////////////////////////////////////////////////////////#if!defined(AFX_MD5CAPI_H__438D2BEF_6F1B_4C5C_830F_0E7B6D1FD7E2__INCLUDED_)#defineAFX_MD5CAPI_H__438D2BEF_6F1B_4C5C_830F_0E7B6D1FD7E2__INCLUDED_#if_MSC_VER1000#pragmaonce#endif//_MSC_VER1000#includewincrypt.h//CryptographicAPIPrototypesandDefinitionsclassCmd5Capi{public:CString&Digest(CString&csBuffer);CString&GetDigest(void);Cmd5Capi(CString&csBuffer);Cmd5Capi();virtual~Cmd5Capi();CStringcsDigest;};#endif////////////////////////////////////////////////////////////////////////md5Capi.cpp:implementationoftheCmd5Capiclass.//CalculeMD5DigestusingtheWINCryptoAPI.////////////////////////////////////////////////////////////////////////#includestdafx.h#includemd5Capi.h#ifdef_DEBUG#undefTHIS_FILEstaticcharTHIS_FILE[]=__FILE__;#definenewDEBUG_NEW#endif////////////////////////////////////////////////////////////////////////Construction/Destruction//////////////////////////////////////////////////////////////////////Cmd5Capi::Cmd5Capi(){csDigest.Empty();}Cmd5Capi::Cmd5Capi(CString&csBuffer){Digest(csBuffer);}Cmd5Capi::~Cmd5Capi(){}CString&Cmd5Capi::GetDigest(void){returncsDigest;}CString&Cmd5Capi::Digest(CString&csBuffer){HCRYPTPROVhCryptProv;HCRYPTHASHhHash;BYTEbHash[0x7f];DWORDdwHashLen=16;//TheMD5algorithmalwaysreturns16bytes.DWORDcbContent=csBuffer.GetLength();BYTE*pbContent=(BYTE*)csBuffer.GetBuffer(cbContent);if(CryptAcquireContext(&hCryptProv,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT|CRYPT_MACHINE_KEYSET)){if(CryptCreateHash(hCryptProv,CALG_MD5,//algorithmidentifierdefinitionssee:wincrypt.h0,0,&hHash)){if(CryptHashData(hHash,pbContent,cbContent,0)){if(CryptGetHashParam(hHash,HP_HASHVAL,bHash,&dwHashLen,0)){//MakeastringversionofthenumericdigestvaluecsDigest.Empty();CStringtmp;for(inti=0;i16;i++){tmp.Format(%02x,bHash[i]);csDigest+=tmp;}}elsecsDigest=_T(Errorgettinghashparam);}elsecsDigest=_T(Errorhashingdata);}elsecsDigest=_T(Errorcreatinghash);}elsecsDigest=_T(Erroracquiringcontext);CryptDestroyHash(hHash);CryptReleaseContext(hCryptProv,0);csBuffer.ReleaseBuffer();returncsDigest;}
本文标题:MD5算法简介及两种实现方法(使用WindowsAPI函数)
链接地址:https://www.777doc.com/doc-1085045 .html