Microsoft CryptoAPI加密技術_第1頁
Microsoft CryptoAPI加密技術_第2頁
Microsoft CryptoAPI加密技術_第3頁
Microsoft CryptoAPI加密技術_第4頁
Microsoft CryptoAPI加密技術_第5頁
已閱讀5頁,還剩8頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、MicrosoftCryptoAPI加密技術簡介加密API在企業計算模型(EnterpriseComputingModel)中有著重要的應用。企業計算化程度意味著人的接觸更全球化,例如國際商品貿易,州際庫存管理等等。在這些領域中經常要通過不安全渠道傳輸敏感信息例如電傳合同,通過電子郵件收發訂單,及種種其它情況。使用加密API(CryptographyAPI),你就能夠保證信息的安全性。加密API總覽加密服務提供者模塊(CryptographyServiceProviderCSP)當對用戶的私有敏感數據提供保護時,加密API中的函數允許應用程序以一種靈活的方式來加密或者電子簽名數據。所有加密操作

2、都由獨立的模塊來實施,這些模塊叫作加密服務提供者(cryptographicserviceprovider)。操作系統中已經包含了一個CSP,名叫“MicrosoftRSABaseProvider”。每個CSP都對加密API層提供一個不同的實現。一些提供強加密算法,而另一些會包含如智能卡(smartcards,智能卡是一張嵌有包含用戶安全信息芯片的塑料卡片)之類的硬件部件。另外,一些CSP可能會直接與用戶交互,如使用用戶的簽名私鈅進行數據簽名時。應用程序不要使用依賴于特定CSP的屬性。例如,“MicrosoftRSABaseProvider”目前使用40位的會話密鈅(sessionkeys)和

3、512位的公鈅(publickeys)。當程序維護這些的時候,要小心的不要假定需要使用多大的內存去存儲它們。另外,當用戶在系統中安裝一個不同的CSP后,程序很可能出錯。你要努力使寫出的程序盡可能的well-behavedandflexible(行為良好且易擴展)。密鈅庫每個CSP都有一個密鈅庫(keydatabase),里面存儲著由CSP保存的算法密鈅。每個密鈅庫都包含一個或多個密鈅容器(keycontainer),每個容器都包含所有屬于特定用戶(或使用加密API的客戶端程序)的密鈅對。每個密鈅容器都被賦與一個唯一的名字,這個名字是程序要獲得此容器句柄時傳給函數CryptAcquireCont

4、ext的參數。加密當進行數據加密時,明文消息(plain-textmessage)在被編碼后會看起來象完全隨機的二進制數據,以至于沒有密鈅就很難將其轉化為原來的消息。本文中使用如下定義:消息(Message):指任何數據塊。消息可以是ASCII文本,一個數據庫文件或者任何你要安全存儲或者傳輸的數據。明文(Plaintext):指沒有被加密的數據。密文(Ciphertext):指被加密過的數據。一旦消息被加密,它就可以存儲在非安全的介質上或者通過非安全的網絡傳輸而仍然保持安全。之后,消息可以解密回原來的格式。當加密消息時,要使用加密密鈅(encryptionkey)。這就類型于用一把鑰匙去鎖一把

5、鎖一樣。當解密這個消息時,必須用相應的解密密鈅(decryptionkey)。對解密密鈅的嚴格限制訪問非常重要,因為任何拿到它的人可以解開用相應的加密密鈅加密的所有消息。真正的難點是安全的保存密鈅和安全的將密鈅傳輸到其它人那。有兩種主要的加密算法:對稱算法(symmetricalgorithms)與公鈅算法(public-keyalgorithms)也叫做非對稱算法(asymmetricalgorithms)。使用對稱算法的系統有時歸入傳統型(conventional)中。算法對稱算法是最普遍的加密算法類型。它們叫“對稱”是因為使用相同的密鈅進行加密與解密。與使用公鈅算法的密鈅不同,對稱密鈅是

6、經常變化的。因為這個原因,此處將它們歸于會話密鈅。與公鈅算法相比,對稱算法非常快,因此最適于加密大量數據的情況。一些最常用的對稱加密算法是RC2,RC4,與數據加密標準(DataEncryptionStandard,DES)。(譯注:單重DES因密鈅長度已不適應當前的加密環境,最好不用。可以使用三重DES,或者AES)公鈅(非對稱)算法使用一對不同的密鈅:一個公鈅和一個私鈅。私鈅由密鈅對的所有者自己保存,公鈅可以自由分發給所有要求得到的人。如果用一個密鈅加密一個消息,必須用另一個密鈅解密此消息。公鈅算法很慢,要比對稱算法慢數千倍。因此它們一般僅用來加密會話密鈅。它們也用來對消息進行數字簽名(d

7、igitallysign),下一部分會討論這個內容。最常用的公鈅加密算法之一是RSAPublic-KeyCipher。文件簽名數字簽名(Digitalsignatures)用在你要以明文形式分發一個消息,并且你想要讓接收者能夠驗證這個消息自從離開你手后沒有被篡改過。對消息簽名并不會改變消息,它僅生成一個可附著在消息上或者單獨傳輸的數字簽名。數字簽名使用公鈅算法生成。使用私鈅來生成,并且使用相對應的公鈅來驗證。幾個加密API函數初始化CSP:CryptAcquireContext,CryptReleaseContext函數CryptAcquireContext用來獲得CSP中一個特定密鈅容器的句

8、柄。返回的句柄然后就可以對選擇的CSP進行調用。函數CryptReleaseContext用于釋放函數CryptAcquireContext返回的句柄。CryptReleaseContext不會刪除任何CryptographyAPI對象,它僅僅釋放對象的句柄。函數CryptAcquireContext執行兩個操作。首先試著查找變量中指定的CSP,如果找到,函數試著查找CSP中匹配指定密鈅容器名的密鈅容器。此函數也可以用于建立、刪除密鈅容器,這取決于函數中的參數值。取得默認CSP中默認密鈅容器的代碼如下所示:#include/對CryptoAPI的定義/*對于非C/C+用戶,此處用到的常量如下:

9、#defineMS_DEF_PROVMicrosoftBaseCryptographicProviderv1.0#definePROV_RSA_FULL1*/BOOLbResult;HCRYPTPROChProv;/試圖取得轉為密鈅容器的句柄bResult=CryptAcquireContext(&hProv,/保存返回句柄的變量NULL,/默認密鈅容器MS_DEF_PROV,/默認CSPPROV_RSA_FULL,/要取得的CSP類型0);/未指定動作/在此處執行操作/釋放容器句柄CryptReleaseContext(hProv);如果CryptAcquireContext調用成功,返回值

10、非零,變量hProv即為要取得的密鈅容器句柄。要在默認CSP中添加或者創建一個密鈅容器,要寫的代碼如下:#include/對CryptoAPI的定義/*對于非C/C+用戶,此處用到的常量如下:#defineMS_DEF_PROVMicrosoftBaseCryptographicProviderv1.0#definePROV_RSA_FULL1#defineCRYPT_NEWKEYSET0 x8*/BOOLbResult;HCRYPTPROChProv;/試圖添加一個新的密鈅容器BResult=CryptAcquireContext(&hProv,/保存返回句柄的變量NULL,/默認密鈅容器M

11、S_DEF_PROV,/默認CSPPROV_RSA_FULL,/要取得的CSP類型CRYPT_NEWKEYSET);/創建一個新密鈅容器./在此處執行操作./釋放容器句柄CryptReleaseContext(hProv);如果CryptAcquireContext調用成功,返回值非零,變量hProv即為新的密鈅容器句柄。要從默認CSP中刪除一個存在的密鈅容器,要寫的代碼如下:#include/對CryptoAPI的定義/*對于非C/C+用戶,此處用到的常量如下:#defineMS_DEF_PROVMicrosoftBaseCryptographicProviderv1.0#definePRO

12、V_RSA_FULL1#defineCRYPT_DELETEKEYSET0 x10*/BOOLbResult;HCRYPTPROChProv;/試圖刪除密鈅容器BResult=CryptAcquireContext(&hProv,/保存返回句柄的變量NULL,/默認密鈅容器MS_DEF_PROV,/默認CSPPROV_RSA_FULL,/要取得的CSP類型/釋放散列對象/獲得散列對象句柄CRYPT_DELETEKEYSET);/刪除存在的密鈅容器如果CryptAcquireContext調用成功,返回值非零,變量hProv指向的密鈅容器已經刪除,此密鈅容器不再有效。散列數據:CryptCrea

13、teHash,CryptHashData,CryptGetHashParam,CryptDestroyHash當我說“散列法”或“散列”(hashingorhash)時,是指從一塊數據中派生出一個數值的方法或算法。這可能是簡單的將所有數據位相加,或復雜到要對數據進行傅立葉變換。(譯注:散列也被稱為哈希,雜湊)上面列出的四個函數是用于創建或者維護從提供的數據生成的散列值的,一般一起使用:函數CryptCreateHash用于散列數據時初始化。它返回CSP散列對象的句柄,此句柄會在后續CryptHashData函數散列數據時使用。下一步是調用CryptGetHashParam函數取得散列值。函數C

14、ryptDestroyHash釋放函數CryptCreateHash返回的句柄。CryptDestroyHash不會刪除任何加密API對象,它僅僅釋放散列對象的句柄。CryptHashData函數用來從提供的數據中計算密碼散列。為計算一個大數據塊或者數據塊的幾個部分時,此函數可被調用多次。例如,我們要對緩沖區pBuffer中dwBufferLen字節長的數據進行散列。在此例子中我僅使用CALG_MD5散列算法來實現此目的。加密APISDK文檔中還提供對許多其它算法詳細的描述。本例子假定只散列一塊數據。一旦調用CryptGetHashParam函數取得了散列值,此散列實例對象便不能再散列其它數據

15、了。#include/對CryptoAPI的定義/*對于非C/C+用戶,此處用到的常量如下:#defineALG_CLASS_HASH(413)#defineALG_TYPE_ANY(0)#defineALG_SID_MD53#defineCALG_MD5(ALG_CLASS_HASH|ALG_TYPE_ANY|ALG_SID_MD5)#defineHP_HASHVAL0 x0002/散列值#defineHP_HASHSIZE0 x0004/散列值長度*/BOOLbResult;HCRYPTHASHhHash;DWORDdwBufferSize;DWORDdwValue;PBYTEpBuffe

16、r;bResult=CryptCreateHash(hProv,/之前獲得的CSP句柄CALG_MD5,/散列算法0,/非密鈅散列0,/置0&hHash);/保存散列對象句柄的變量/散列數據bResult=CryptHashData(hHash,/散列對象句柄pBuffer,/數據緩沖區指針dwBufferlen,/數據長度0);/未指定值/得到散列值尺寸dwBufferSize=sizeof(DWORD);bResult=CryptGetHashParam(hHash,/散列對象句柄HP_HASHSIZE,/得到散列值尺寸&dwValue,/保存散列值長度緩沖區&dwBufferSize,/

17、緩沖區長度0);/必須置0/創建保存散列值的緩沖區pBuffer=newchardwBufferSize;/Gethashvalue.bResult=CryptGetHashParam(hHash,/散列對象句柄HP_HASHVAL,/得到散列值pBuffer,/保存散列值長度緩沖區&dwBufferSize,/緩沖區長度0);/必須置0CryptDestroyHash(hHash);上面例子為pBuffer指向的數據生成一個散列值。如果還要散列其它數據,用這個數據調用CryptHashData,產生的散列值仍會是原來的值。已警告過一使用HP_HASHVALUE參數調用CryptGetHash

18、Param會阻止使用此對象繼續進行散列。生成密鈅:CryptDeriveKey,CryptGenKey,CryptDestroyKey這三個函數用來產生密鈅句柄:CryptDeriveKey函數從一個指定的密碼(password)產生密鈅。CryptGenKey函數從一個隨機產生的數值產生密鈅。CryptDestroyKey函數釋放密鈅對象。使用CryptGenKey函數時,建議使用CRYPT_EXPORTABLE參數以創建一個可導出的會話密鈅。這會建立一個可從一臺機器移到另一臺機器的值。不提供此參數,返回值僅在此機器/會話中有效。下面是如何使用CryptDeriveKey函數的例子,假定pP

19、assword指向一個用戶指定的密碼,dwPasswordLength為密碼長度。#include/對CryptoAPI的定義/*對于非C/C+用戶,此處用到的常量如下:#defineALG_CLASS_HASH(413)#defineALG_TYPE_ANY(0)#defineALG_SID_MD53#defineCALG_MD5(ALG_CLASS_HASH|ALG_TYPE_ANY|ALG_SID_MD5)#defineCRYPT_EXPORTABLE0 x00000001#defineALG_CLASS_DATA_ENCRYPT(313)#defineALG_TYPE_STREAM(4

20、9)#defineALG_SID_RC22#defineCALG_RC4(ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_STREAM|ALG_SID_RC4)*/BOOLbResult;HCRYPTHASHhHash;HCRYPTKEYhKey;/釋放密鈅對象/獲得散列對象句柄bResult=CryptCreateHash(hProv,/之前獲得的CSP句柄CALG_MD5,/散列算法0,/非密鈅散列0,/置0&hHash);/保存散列對象句柄的變量/散列數據bResult=CryptHashData(hHash,/散列對象句柄pPassword,/指向密碼的指針dwPass

21、wordLength,/數據長度0);/未指定值/從指定的密碼產生密鈅bResult=CryptDeriveKey(hProv,/之前獲得的CSP句柄CALG_RC4,/流加密hHash,/密碼散列后對象句柄CRYPT_EXPORTABLE,/密鈅可導出&hKey);/保存密鈅對象句柄的變量/用密鈅進行操作/釋放散列對象CryptDestroyHash(hHash);CryptDestroyKey(hKey);/加密數據加密與解密數據:CryptEncrypt,CryptDecrypt簡單來說,盡管不全對,加密API處理數據是圍繞兩個函數一加密(CryptEncrypt)與解密(CryptDe

22、crypt)。這兩個函數非常易用,但需要對其參數進行一下說明:每個函數的頭六個參數是相同的頭兩個參數僅是密鈅句柄和一個可選的散列對象第三個參數是一個布爾值,此值在最后一塊數據塊之前保持為FALSE,為讓函數對最后一塊數據進行特殊處理,在最后一塊數據時置為TRUE第四與第五個參數是標志值和一個指向加密或解密數據的指針第六個參數是緩沖區中待加密字符的數量第七個參數通常與第六個參數相同,它指出數據塊長度。這是因為對于許多算法來說,加密數據尺寸與解密數據尺寸是相同的。然而,某些算法增加加密數據的長度。在這種情況下,第五個參數中的緩沖區必須大到足以容納額外的數據。緩沖區長度的問題可以在加密前通過調用Cr

23、yptEncrypt函數返回需要緩沖區的尺寸來解決。下面的例子代碼演示了這種技術。在這個例子中,某些值已假定之前已獲得,我們僅要加密pData指向的緩沖區中dwDataLen字節長的數據。BOOLbResult;PBYTEpBuffer;DWORDdwSize;/將緩沖中數據長度賦給變量dwSize=dwDataLen;/讓API返回給我們需要的緩沖長度bResult=CryptEncrypt(hKey,/之前獲得的密鈅對象0,/不散列數據TRUE,/最后的還是緩沖的數據0,/必須置0NULL,/無數據,簡單的返回尺寸&dwSize,/數據的尺寸dwSize);/數據塊尺寸/現在得到了輸出緩沖

24、區尺寸,創建此緩沖區pBuffer=newchardwSize;bResult=CryptEncrypt(hKey,/之前獲得的密鈅對象0,/不散列數據TRUE,/最后的還是緩沖的數據0,/必須置0pBuffer,/數據緩沖區&dwSize,/數據尺寸dwSize);/數據塊尺寸同時進行加密與解密當使用同一個密鈅進行加密或解密兩個數據流時,必須采取一些措施。同一個物理會話密鈅不得被用于同一個操作,因為每個會話密鈅容器的內部狀態信息在同時進行一個操作時會混亂。對此問題的簡單解決辦法是制作一份會話密鈅的拷貝。這樣,原始密鈅進行一個操作,拷貝密鈅進行另一個操作。制作一個會話密鈅的拷貝可以通過調Cry

25、ptExportKey導出密鈅,然后調CryptlmportKey將它導進來。密鈅導入后,CSP會給這個“新”的密鈅分配自己的內部內存區域,就好象它跟原來的密鈅完全沒有關聯一樣。CRYPTOAPI例程程序有下列命令行結構。Usage:EncryptswitchargumentsWhereswitchandoptionalargumentsareoneof:SwitchArgumentsDescription/ADDUSERtoaddusertoCSPtable/REMOVEUSERtoremoveuserfromCSPtable/ENCRYPTufefpwdtoencryptafile/DEC

26、RYPTefufpwdtodecryptafile/SIGNufsfdesctosignafile/VERIFYufsfdesctoverifyasignedfile/CSPtoshowCSPstatisticsanduf=nameofanunencryptedfileef=nameofanencryptedfilesf=nameofasignedfilepwd=optionalpassworddesc=optionalsignaturedescription編碼問題需要顯式地在例程中定義特定的常量,因為加密API頭文件(wincrypt.h)使用_WIN32_WINNT常量來檢測正在使用哪個

27、WindowsNT版本。當寫此例程時,此常量盡管需要,但當前的編譯器仍然未定義它。定義此常量代碼才不會編譯出錯,可以在以后的編譯器定義它后再將其移除。API函數CryptAcquireContext有一個未文檔化的常量值MS_DEF_PROV。這個常量用來指代默認CSP。這個值用在/ADDUSER命令行開關中。這允許程序使用任何已安裝的CSP,不需要知道其名字。增加或者刪除一個用戶/ADDUSER與/REMOVERUSER開關用來增加或刪除一個默認的加密客戶端。為使其它加密功能運行正常,/ADDUSER開關必須首先被調用。下面一系列操作會被執行:一個默認密鈅容器被創建一個數字簽名密鈅對在密鈅容器中被創建一個密鈅交換密鈅對在密鈅容器中被創建這項操作僅需執行一次,除非操作系統重裝。假如默認的密鈅容器與密鈅對已經創建,那么再次使用這個開關沒有效果。從命令行運行/ADDUSER開關如下:Encrypt/ADDUSER從命令行運行/REMOVEUSER開關如下:Encrypt/REMOVEUSER加密或解密文件/ENCRYPT開關用來加密文件。通過這個開關加密的文件以后可以通過/DECRYPT開關解密。注意:為了給默認用戶創建一個密鈅容器,必須在進行任何加密前調用/ADDUSER開關。從命令行運行/ENCRYPT開關如下:Encrypt/encryptvso

溫馨提示

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

評論

0/150

提交評論