MicrosoftCryptoAPI實(shí)例介紹說(shuō)明_第1頁(yè)
MicrosoftCryptoAPI實(shí)例介紹說(shuō)明_第2頁(yè)
MicrosoftCryptoAPI實(shí)例介紹說(shuō)明_第3頁(yè)
MicrosoftCryptoAPI實(shí)例介紹說(shuō)明_第4頁(yè)
MicrosoftCryptoAPI實(shí)例介紹說(shuō)明_第5頁(yè)
已閱讀5頁(yè),還剩15頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

MicrosoftCryptoAPI實(shí)例介紹在這個(gè)信息爆炸的時(shí)代,我們不得不對(duì)信息的安全提高警惕。加密作為保障數(shù)據(jù)信息安全的一種方式,越來(lái)越受到人們的關(guān)注。下面,我將把自己對(duì)MicrosoftCryptoAPI的一些膚淺的理解與大家共享,有什么不妥之處望不吝賜教。一、加密方法:當(dāng)初,計(jì)算機(jī)的研究就是為了破解德國(guó)人的密碼,人們并沒(méi)有想到計(jì)算機(jī)給今天帶來(lái)的信息革命。隨著計(jì)算機(jī)的發(fā)展,運(yùn)算能力的增強(qiáng),密碼學(xué)已經(jīng)取得了巨大的進(jìn)展。大體來(lái)說(shuō)有以下幾種形式。1、公用密鑰加密技術(shù)加密和解密使用不同的密鑰,分別叫做“公鑰”和“私鑰”。顧名思義,“私鑰”就是不能讓別人知道的,而“公鑰”就是可以公開(kāi)的。這兩個(gè)必須配對(duì)使用,用公鑰加密的數(shù)據(jù)必須用與其對(duì)應(yīng)的私鑰才能解開(kāi)。這種技術(shù)安全性高,得到廣泛運(yùn)用,但是效率太低。2、對(duì)稱(chēng)密鑰加密技術(shù)要求加密和解密過(guò)程使用相同的密鑰,這樣,密鑰必須只能被加解密雙方知道,否則就不安全。這種技術(shù)安全性不高,但是效率高。3、結(jié)合公用和對(duì)稱(chēng)密鑰加密技術(shù)公鑰加密技術(shù)以速度為代價(jià)換取了高安全性,而對(duì)稱(chēng)加密以低安全換取高性能,所以另一種常見(jiàn)的加密方法就是結(jié)合以上兩種技術(shù)。用對(duì)稱(chēng)加密算法對(duì)數(shù)據(jù)進(jìn)行加密,然后使用更安全的但效率更低的公鑰加密算法對(duì)對(duì)稱(chēng)密鑰進(jìn)行加密。4、數(shù)字簽名和鑒別就是對(duì)已經(jīng)加密的數(shù)據(jù)“簽名”,這樣接收者可以知道加密的數(shù)據(jù)的來(lái)源,以及是否被更改。二、CryptoAPI微軟的CryptoAPI是PKI推薦使用的加密API。其功能是為應(yīng)用程序開(kāi)發(fā)者提供在Win32環(huán)境下使用加密、驗(yàn)證等安全服務(wù)時(shí)的標(biāo)準(zhǔn)加密接口。CryptoAPI處于應(yīng)用程序和CSP(cryptographicserviceprovider)之間(見(jiàn)下圖)。CryptoAPI的編程模型同Windows系統(tǒng)的圖形設(shè)備接口GDI比較類(lèi)似,其中加密服務(wù)提供者CSP等同于圖形設(shè)備驅(qū)動(dòng)程序,加密硬件(可選)等同于圖形硬件,其上層的應(yīng)用程序也類(lèi)似,都不需要同設(shè)備驅(qū)動(dòng)程序和硬件直接打交道。CryptoAPI共有五部分組成:簡(jiǎn)單消息函數(shù)(SimplifiedMessageFunctions)、低層消息函數(shù)(Low-levelMessageFunctions)、基本加密函數(shù)(BaseCryptographicFunctions)、證書(shū)編解碼函數(shù)(CertificateEncode/DecodeFunctions)和證書(shū)庫(kù)管理函數(shù)(CertificateStoreFunctions)。其中前三者可用于對(duì)敏感信息進(jìn)行加密或簽名處理,可保證網(wǎng)絡(luò)傳輸信心的私有性;后兩者通過(guò)對(duì)證書(shū)的使用,可保證網(wǎng)絡(luò)信息交流中的認(rèn)證性。三、CSP看到這里,大家也許對(duì)CSP還比較迷惑。其實(shí)CSP是真正實(shí)行加密的獨(dú)立模塊,他既可以由軟件實(shí)現(xiàn)也可以由硬件實(shí)現(xiàn)。但是他必須符合CryptoAPI接口的規(guī)范。每個(gè)CSP都有一個(gè)名字和一個(gè)類(lèi)型。每個(gè)CSP的名字是唯一的,這樣便于CryptoAPI找到對(duì)應(yīng)的CSP。目前已經(jīng)有9種CSP類(lèi)型,并且還在增長(zhǎng)。下表列出出它們支持的密鑰交換算法、簽名算法、對(duì)稱(chēng)加密算法和Hash算法。(表一)CSP類(lèi)型交換算法簽名算法對(duì)稱(chēng)加密算法Hash算法PROV_RSA_FULLRSARSARC2RC4MD5SHAPROV_RSA_SIGnoneRSAnoneMD5SHAPROV_RSA_SCHANNELRSARSARC4DESTripleDESMD5SHAPROV_DSSDSSnoneDSSMD5SHAPROV_DSS_DHDHDSSCYLINK_MEKMD5SHAPROV_DH_SCHANNELDHDSSDESTripleDESMD5SHAPROV_FORTEZZAKEADSSSkipjackSHAPROV_MS_EXCHANGERSARSACASTMD5PROV_SSLRSARSAVariesVaries從圖一可以看到,每個(gè)CSP有一個(gè)密鑰庫(kù),密鑰庫(kù)用于存儲(chǔ)密鑰。而每個(gè)密鑰庫(kù)包括一個(gè)或多個(gè)密鑰容器(KeyContainers)。每個(gè)密鑰容器中含屬于一個(gè)特定用戶(hù)的所有密鑰對(duì)。每個(gè)密鑰容器被賦予一個(gè)唯一的名字。在銷(xiāo)毀密鑰容器前CSP將永久保存每一個(gè)密鑰容器,包括保存每個(gè)密鑰容器中的公/私鑰對(duì)(見(jiàn)圖二)。四、創(chuàng)建密鑰容器,得到CSP句柄說(shuō)了這么多只是一些理論性的東西,后面將詳細(xì)介紹一下MicrosoftCryptoAPI的使用方法。我們已經(jīng)提過(guò),每一個(gè)CSP都有一個(gè)名字和一個(gè)類(lèi)型,并且名字保證唯一。所以可以通過(guò)名字和類(lèi)型得到一個(gè)CSP。然而,要想加密肯定需要密鑰,那么密鑰放哪里呢?對(duì)了,就放在密鑰容器。(有人會(huì)問(wèn),密碼庫(kù)有什么用?其實(shí)密鑰庫(kù)是在安裝CSP的時(shí)候已經(jīng)存在了,他與CSP是相對(duì)應(yīng)的。)但是密鑰容器并不是一開(kāi)始就存在的,需要用戶(hù)去創(chuàng)建。下面的代碼實(shí)現(xiàn)以上功能(得到CSP即密碼容器)。if(CryptAcquireContext(&hCryptProv,//返回CSP句柄UserName,//密碼容器名NULL,//NULL時(shí)使用默認(rèn)CSP名(微軟RSABaseProvider)PROV_RSA_FULL,//CSP類(lèi)型0))//Flagvalues{//以UserName為名的密鑰容器存在,那么我們已經(jīng)得到了CSP的句柄printf("Acryptocontextwiththe%skeycontainer\n",UserName);printf("hasbeenacquired.\n\n");}else//如果密鑰容器不存在,我們需要?jiǎng)?chuàng)建這個(gè)密鑰容器{if(CryptAcquireContext(&hCryptProv,UserName,NULL,PROV_RSA_FULL,CRYPT_NEWKEYSET))//創(chuàng)建以UserName為名的密鑰容器{ //創(chuàng)建密鑰容器成功,并得到CSP句柄printf("Anewkeycontainerhasbeencreated.\n");}else{HandleError("Couldnotcreateanewkeycontainer.\n");}}//Endofelse好了,我們已經(jīng)創(chuàng)建了密鑰容器,并得到了CSP的句柄。也可以這樣理解,我們得到了一個(gè)CSP的句柄,并且它被綁定到以UserName為名的密鑰容器上。那么,以后的加解密等操作,都將在這個(gè)CSP上進(jìn)行??梢匀缦聞h除密鑰容器。CryptAcquireContext(&hCryptProv,userName,NULL,PROV_RSA_FULL,CRYPT_DELETEKEYSET);五、一個(gè)文件加密的例子言歸正傳,我們來(lái)看一段文件加密的代碼。#include<stdio.h>#include<windows.h>#include<wincrypt.h>#defineMY_ENCODING_TYPE(PKCS_7_ASN_ENCODING|X509_ASN_ENCODING)#defineKEYLENGTH0x00800000voidHandleError(char*s);//--------------------------------------------------------------------//Theseadditional#definestatementsarerequired.#defineENCRYPT_ALGORITHMCALG_RC4#defineENCRYPT_BLOCK_SIZE8//DeclarethefunctionEncryptFile.Thefunctiondefinition//followsmain.BOOLEncryptFile( PCHARszSource, PCHARszDestination, PCHARszPassword);//--------------------------------------------------------------------//Beginmain.voidmain(void){CHARszSource[100];CHARszDestination[100];CHARszPassword[100]; printf("Encryptafile.\n\n"); printf("Enterthenameofthefiletobeencrypted:"); scanf("%s",szSource); printf("Enterthenameoftheoutputfile:"); scanf("%s",szDestination); printf("Enterthepassword:"); scanf("%s",szPassword); //-------------------------------------------------------------------- //CallEncryptFiletodotheactualencryption. if(EncryptFile(szSource,szDestination,szPassword)) { printf("Encryptionofthefile%swasasuccess.\n",szSource); printf("Theencrypteddataisinfile%s.\n",szDestination); } else { HandleError("Errorencryptingfile!"); }}//Endofmain//--------------------------------------------------------------------//CodeforthefunctionEncryptFilecalledbymain.staticBOOLEncryptFile( PCHARszSource, PCHARszDestination, PCHARszPassword) //-------------------------------------------------------------------- //Parameterspassedare: //szSource,thenameoftheinput,aplaintextfile. //szDestination,thenameoftheoutput,anencryptedfiletobe //created. //szPassword,thepassword.{ //-------------------------------------------------------------------- //Declareandinitializelocalvariables. FILE*hSource; FILE*hDestination; HCRYPTPROVhCryptProv; HCRYPTKEYhKey; HCRYPTHASHhHash; PBYTEpbBuffer; DWORDdwBlockLen; DWORDdwBufferLen; DWORDdwCount; //-------------------------------------------------------------------- //Opensourcefile. if(hSource=fopen(szSource,"rb")) { printf("Thesourceplaintextfile,%s,isopen.\n",szSource); } else { HandleError("Erroropeningsourceplaintextfile!"); } //-------------------------------------------------------------------- //Opendestinationfile. if(hDestination=fopen(szDestination,"wb")) { printf("Destinationfile%sisopen.\n",szDestination); } else { HandleError("Erroropeningdestinationciphertextfile!"); } //以下獲得一個(gè)CSP句柄 if(CryptAcquireContext( &hCryptProv, NULL, //NULL表示使用默認(rèn)密鑰容器,默認(rèn)密鑰容器名//為用戶(hù)登陸名 NULL, PROV_RSA_FULL, 0)) { printf("Acryptographicproviderhasbeenacquired.\n"); } else { if(CryptAcquireContext( &hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))//創(chuàng)建密鑰容器 { //創(chuàng)建密鑰容器成功,并得到CSP句柄 printf("Anewkeycontainerhasbeencreated.\n"); } else { HandleError("Couldnotcreateanewkeycontainer.\n"); } } //-------------------------------------------------------------------- //創(chuàng)建一個(gè)會(huì)話(huà)密鑰(sessionkey) //會(huì)話(huà)密鑰也叫對(duì)稱(chēng)密鑰,用于對(duì)稱(chēng)加密算法。 //(注:一個(gè)Session是指從調(diào)用函數(shù)CryptAcquireContext到調(diào)用函數(shù) //CryptReleaseContext期間的階段。會(huì)話(huà)密鑰只能存在于一個(gè)會(huì)話(huà)過(guò)程) //-------------------------------------------------------------------- //Createahashobject. if(CryptCreateHash( hCryptProv, CALG_MD5, 0, 0, &hHash)){printf("Ahashobjecthasbeencreated.\n");}else{ HandleError("ErrorduringCryptCreateHash!\n");} //-------------------------------------------------------------------- //用輸入的密碼產(chǎn)生一個(gè)散列 if(CryptHashData( hHash, (BYTE*)szPassword, strlen(szPassword), 0)) { printf("Thepasswordhasbeenaddedtothehash.\n"); } else { HandleError("ErrorduringCryptHashData.\n"); } //-------------------------------------------------------------------- //通過(guò)散列生成會(huì)話(huà)密鑰 if(CryptDeriveKey( hCryptProv, ENCRYPT_ALGORITHM, hHash, KEYLENGTH, &hKey)) { printf("Anencryptionkeyisderivedfromthepasswordhash.\n"); } else { HandleError("ErrorduringCryptDeriveKey!\n"); } //-------------------------------------------------------------------- //Destroythehashobject. CryptDestroyHash(hHash); hHash=NULL; //-------------------------------------------------------------------- //Thesessionkeyisnowready. //-------------------------------------------------------------------- //因?yàn)榧用芩惴ㄊ前碋NCRYPT_BLOCK_SIZE大小的塊加密的,所以被加密的//數(shù)據(jù)長(zhǎng)度必須是ENCRYPT_BLOCK_SIZE的整數(shù)倍。下面計(jì)算一次加密的//數(shù)據(jù)長(zhǎng)度。 dwBlockLen=1000-1000%ENCRYPT_BLOCK_SIZE; //-------------------------------------------------------------------- //Determinetheblocksize.Ifablockcipherisused, //itmusthaveroomforanextrablock. if(ENCRYPT_BLOCK_SIZE>1) dwBufferLen=dwBlockLen+ENCRYPT_BLOCK_SIZE; else dwBufferLen=dwBlockLen; //-------------------------------------------------------------------- //Allocatememory. if(pbBuffer=(BYTE*)malloc(dwBufferLen)) { printf("Memoryhasbeenallocatedforthebuffer.\n"); } else { HandleError("Outofmemory.\n"); } //-------------------------------------------------------------------- //Inadoloop,encryptthesourcefileandwritetothesourcefile. do { //-------------------------------------------------------------------- //ReaduptodwBlockLenbytesfromthesourcefile. dwCount=fread(pbBuffer,1,dwBlockLen,hSource); if(ferror(hSource)) { HandleError("Errorreadingplaintext!\n"); } //-------------------------------------------------------------------- //加密數(shù)據(jù) if(!CryptEncrypt( hKey, //密鑰 0, //如果數(shù)據(jù)同時(shí)進(jìn)行散列和加密,這里傳入一個(gè)//散列對(duì)象 feof(hSource), //如果是最后一個(gè)被加密的塊,輸入TRUE.如果不是輸. //入FALSE這里通過(guò)判斷是否到文件尾來(lái)決定是否為//最后一塊。 0, //保留 pbBuffer, //輸入被加密數(shù)據(jù),輸出加密后的數(shù)據(jù) &dwCount, //輸入被加密數(shù)據(jù)實(shí)際長(zhǎng)度,輸出加密后數(shù)據(jù)長(zhǎng)度 dwBufferLen)) //pbBuffer的大小。 { HandleError("ErrorduringCryptEncrypt.\n"); } //-------------------------------------------------------------------- //Writedatatothedestinationfile. fwrite(pbBuffer,1,dwCount,hDestination); if(ferror(hDestination)) { HandleError("Errorwritingciphertext."); } } while(!feof(hSource)); //-------------------------------------------------------------------- //Endthedoloopwhenthelastblockofthesourcefilehasbeen //read,encrypted,andwrittentothedestinationfile. //-------------------------------------------------------------------- //Closefiles. if(hSource) fclose(hSource); if(hDestination) fclose(hDestination); //-------------------------------------------------------------------- //Freememory. if(pbBuffer) free(pbBuffer); //-------------------------------------------------------------------- //Destroysessionkey. if(hKey) CryptDestroyKey(hKey); //-------------------------------------------------------------------- //Destroyhashobject. if(hHash) CryptDestroyHash(hHash); //-------------------------------------------------------------------- //Releaseproviderhandle. if(hCryptProv) CryptReleaseContext(hCryptProv,0); return(TRUE);}//EndofEncryptfile//--------------------------------------------------------------------//ThisexampleusesthefunctionHandleError,asimpleerror//handlingfunction,toprintanerrormessagetothestandarderror//(stderr)fileandexittheprogram.//Formostapplications,replacethisfunctionwithone//thatdoesmoreextensiveerrorreporting.voidHandleError(char*s){fprintf(stderr,"Anerroroccurredinrunningtheprogram.\n");fprintf(stderr,"%s\n",s);fprintf(stderr,"Errornumber%x.\n",GetLastError());fprintf(stderr,"Programterminating.\n");exit(1);}//EndofHandleError(注:如果代碼編譯不過(guò),加入宏定義:_WIN32_WINNT=0x0400)六、公用密鑰加密技術(shù)公用密鑰加密技術(shù)使用兩個(gè)不同的密鑰:公鑰和私鑰。私鑰必須安全的保管好不能被外人知道,而公鑰可以告訴任何人,只要他需要。通常公鑰是以數(shù)字證書(shū)的形式發(fā)布的。用公私密鑰對(duì)中的一個(gè)密鑰加密的數(shù)據(jù)只能用密鑰對(duì)中的另一個(gè)密鑰才能解密。也就是說(shuō)用用戶(hù)A的公鑰加密的數(shù)據(jù)只能用A的私鑰才能解密,同樣,用A的私鑰加密的數(shù)據(jù)只能用A的公鑰才能解密。如果用私鑰簽名一個(gè)消息,那么必須用與之對(duì)應(yīng)的公鑰去驗(yàn)證簽名的有效性。不幸的是公用密鑰加密技術(shù)的效率非常低甚至只有對(duì)稱(chēng)加密的千分之一,所以不適合對(duì)大量的數(shù)據(jù)進(jìn)行加密。實(shí)際上,公用密鑰加密技術(shù)一般用來(lái)加密會(huì)話(huà)密鑰,而數(shù)據(jù)加密可以用對(duì)稱(chēng)加密的方法。好了,讓我們回到MicrosoftCryptoAPI。我們知道一個(gè)CSP有一個(gè)密鑰庫(kù),這個(gè)密鑰庫(kù)有一個(gè)或多個(gè)密鑰容器。而密鑰容器中有什么呢?一般來(lái)說(shuō),一個(gè)密鑰容器中有兩對(duì)公私密鑰對(duì),一對(duì)用來(lái)加密會(huì)話(huà)密鑰,而另一對(duì)用來(lái)進(jìn)行數(shù)字簽名,也就是大家知道的keyexchangekeypair和signaturekeypair。那么,怎么得到這些密鑰對(duì)呢?if(CryptGetUserKey(hCryptProv,//我們已經(jīng)得到的CSP句柄AT_SIGNATURE,//這里想得到signaturekeypair&hKey))//返回密鑰句柄{printf("Asignaturekeyisavailable.\n");}else //取signaturekeypair錯(cuò)誤{printf("Nosignaturekeyisavailable.\n");if(GetLastError()==NTE_NO_KEY)//密鑰容器里不存在signaturekeypair{//創(chuàng)建signaturekeypair.printf("Thesignaturekeydoesnotexist.\n");printf("Createasignaturekeypair.\n");if(CryptGenKey(hCryptProv, //CSP句柄AT_SIGNATURE, //創(chuàng)建的密鑰對(duì)類(lèi)型為signaturekeypair0, //key類(lèi)型,這里用默認(rèn)值&hKey)) //創(chuàng)建成功返回新創(chuàng)建的密鑰對(duì)的句柄{printf("Createdasignaturekeypair.\n");}else{printf("Erroroccurredcreatingasignaturekey.\n");}}else{printf("AnerrorotherthanNTE_NO_KEYgettingsignature\key.\n");}}//endif將參數(shù)AT_SIGNATURE換成AT_KEYEXCHANGE就可以得到keyexchangekeypair?,F(xiàn)在我們得到的僅僅是一個(gè)句柄,我們需要把這個(gè)key值存儲(chǔ)的磁盤(pán)或文件中,這樣才能傳給對(duì)方來(lái)進(jìn)行解密。下面讓我們來(lái)看一個(gè)用于導(dǎo)出密鑰的API。BOOLWINAPICryptExportKey(HCRYPTKEYhKey,HCRYPTKEYhExpKey,DWORDdwBlobType,DWORDdwFlags,BYTE*pbData,DWORD*pdwDataLen);hKey:需要被導(dǎo)出的密鑰句柄hExpKey:前面咱們提到公用密鑰加密技術(shù)的效率非常低所以公用密鑰加密技術(shù)一般用來(lái)加密會(huì)話(huà)密鑰。這里傳入的密鑰就是用來(lái)加密被導(dǎo)出的密鑰的。也就是說(shuō),被導(dǎo)出的密鑰hKey的數(shù)據(jù)是經(jīng)過(guò)這個(gè)密鑰hExpKey加密的。如果為NULL表示不經(jīng)過(guò)加密直接導(dǎo)出。dwBlobType:被導(dǎo)出的密鑰類(lèi)型,比如公鑰還是私鑰等dwFlags:標(biāo)志位pbData:保存導(dǎo)出的數(shù)據(jù),如果為NULL,pdwDataLen將返回導(dǎo)出數(shù)據(jù)的長(zhǎng)度pdwDataLen:輸入pbData緩沖區(qū)的大小,輸出導(dǎo)出數(shù)據(jù)的長(zhǎng)度下面的例子演示如何導(dǎo)出密鑰。if(CryptExportKey(hKey,NULL,PUBLICKEYBLOB, //導(dǎo)出公鑰0,NULL,&dwBlobLen)) //返回密鑰數(shù)據(jù)長(zhǎng)度{printf("SizeoftheBLOBforthepublickeydetermined.\n");}else{printf("ErrorcomputingBLOBlength.\n");exit(1);}//--------------------------------------------------------------------//AllocatememoryforthepbKeyBlob.if(pbKeyBlob=(BYTE*)malloc(dwBlobLen)){printf("MemoryhasbeenallocatedfortheBLOB.\n");}else{printf("Outofmemory.\n");exit(1);}//--------------------------------------------------------------------//DotheactualexportingintothekeyBLOB.if(CryptExportKey(hKey,NULL,PUBLICKEYBLOB,0,pbKeyBlob, //返回密鑰數(shù)據(jù)&dwBlobLen)) //導(dǎo)出的密鑰數(shù)據(jù)的長(zhǎng)度{printf("ContentshavebeenwrittentotheBLOB.\n");}else{printf("Errorexportingkey.\n");exit(1);}如果要導(dǎo)出用公用密鑰加密技術(shù)加密的密鑰,只要把API的第二個(gè)參數(shù)傳入一個(gè)keyexchangekeypair句柄就可以了。既然有了導(dǎo)出當(dāng)然要有導(dǎo)入。BOOLWINAPICryptImportKey(HCRYPTPROVhProv, //CSP句柄BYTE*pbData, //要導(dǎo)入的密鑰數(shù)據(jù)DWORDdwDataLen, //數(shù)據(jù)長(zhǎng)度HCRYPTKEYhPubKey, //如果數(shù)據(jù)是被加密的這里輸入解密用的密鑰句柄DWORDdwFlags, //標(biāo)志位HCRYPTKEY*phKey //導(dǎo)入后返回的密鑰句柄);這個(gè)API比較簡(jiǎn)單,這里就不舉例說(shuō)明了,在以后的例子里會(huì)看到。七、HASHHash簡(jiǎn)單點(diǎn)講就是把任意一段數(shù)據(jù)經(jīng)過(guò)某種算法生成一段唯一的固定長(zhǎng)度的數(shù)據(jù)。也叫做摘要。為了確保數(shù)據(jù)A免受意外或者故意(惡意)的修改,往往用這段數(shù)據(jù)A產(chǎn)生一個(gè)hash數(shù)據(jù)一起發(fā)送出去,接收方可以通過(guò)相同的hash算法用這段接收到的數(shù)據(jù)A產(chǎn)生一個(gè)新的hash數(shù)據(jù)并與接收到的hash數(shù)據(jù)比較,來(lái)驗(yàn)證數(shù)據(jù)A是否為真實(shí)完整的數(shù)據(jù)。下面的API用來(lái)創(chuàng)建hash對(duì)象BOOLWINAPICryptCreateHash(HCRYPTPROVhProv, //CSP句柄ALG_IDAlgid, //選擇hash算法,比如CALG_MD5等HCRYPTKEYhKey, //HMAC和MAC算法時(shí)有用DWORDdwFlags, //保留,傳入0即可HCRYPTHASH*phHash //返回hash句柄);if(CryptCreateHash(hCryptProv,CALG_MD5,0,0,&hHash)){printf("Anemptyhashobjecthasbeencreated.\n");}else{printf("ErrorduringCryptBeginHash!\n");exit(1);}//Insertcodethatusesthehashobjecthere.//--------------------------------------------------------------------//Afterprocessing,hHashmustbereleased.if(hHash)CryptDestroyHash(hHash); //釋放句柄BOOLWINAPICryptHashData(HCRYPTHASHhHash, //hash對(duì)象BYTE*pbData, //被hash的數(shù)據(jù)DWORDdwDataLen, //數(shù)據(jù)的長(zhǎng)度DWORDdwFlags //微軟的CSP這個(gè)值會(huì)被忽略);下面代碼:BYTE*pbBuffer=(BYTE*)"Thedatathatistobehashed.";DWORDdwBufferLen=strlen((char*)pbBuffer)+1;if(CryptHa

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論