1. 程式人生 > >CSP開發基礎--CayptAPI函式庫介紹

CSP開發基礎--CayptAPI函式庫介紹

基本加密函式

基本加密函式為開發加密應用程式提供了足夠靈活的空間。所有CSP的通訊都是通過這些函式。一個CSP是實現所有加密操作的獨立模組。在每一個應用程式中至少需要提供一個CSP來完成所需的加密操作。如果使用多於一個以上的CSP,在加密函式呼叫中就要指定所需的CSP。微軟基本加密提供者(Microsoft Base Cryptographic Provider),是預設繫結到CryptoAPI 裡的。如果沒有指定其他CSP時,這個CSP 就是卻省的。每一個CSP對CryptoAPI 提供了一套不同的實現。一些提供了更加強大的加密演算法,而其他一些CSP包含了對硬體的支援,比如智慧卡。另外,一些CSP 偶爾和使用者直接通

訊,比如數字簽名就使用了使用者的簽名私鑰。

基本加密函式包含了以下幾種:

1.1服務提供者函式

應用程式使用服務提供者函式來連線和斷開一個CSP。下面就是主要的API:

CryptAcquireContext獲得指定CSP的金鑰容器的控制代碼

CryptContextAddRef對HCRYPTPROV控制代碼增加一個應用計數

CryptEnumProviders列舉當前計算機中的CSP

CryptEnumProviderTypes列舉CSP的型別

CryptGetDefaultProvider對於指定CSP型別的卻省CSP

CryptGetProvParam得到一個CSP的屬性

CryptInstallDefaultContext安裝先前得到的HCRYPTPROV上下文作為當前卻省的上下文

CryptReleaseContext釋放由CryptAcquireContext得到的控制代碼

CryptSetProviderCryptSetProviderEx為指定CSP型別指定一個卻省的CSP

CryptSetProvParam指定一個CSP的屬性

CryptUninstallDefaultContext刪除先前由CryptInstallDefaultContext安裝的卻省上下文

1.2金鑰的產生和交換函式

金鑰產生函式建立、配置和銷燬加密金鑰。他們也用於和其他使用者進行交換金鑰。下面

就是主要的一些函式:

CryptAcquireCertificatePrivateKey對於指定證書上下文得到一個HCRYPTPROV控制代碼和dwKeySpec

CryptDeriveKey從一個密碼中派生一個金鑰

CryptDestoryKey銷燬金鑰

CryptDuplicateKey製作一個金鑰和金鑰狀態的精確複製

CryptExportKey把CSP的金鑰做成BLOB 傳送到應用程式的記憶體空間

CryptGenKey建立一個隨機金鑰

CryptGenRandom產生一個隨機數

CryptGetKeyParam得到金鑰的引數

CryptGetUserKey得到一個金鑰交換或簽名金鑰的控制代碼

CryptImportKey把一個金鑰BLOB傳送到CSP 中

CryptSetKeyParam指定一個金鑰的引數

1.3編碼/解碼函式

有一些編碼/解碼函式,他們可以用來對證書、證書撤銷列表、證書請求和證書擴充套件進行編碼和解碼。

以下就是這幾個函式:

CryptDecodeObject對lpszStructType結構進行解碼

CryptDecodeObjectEx對lpszStructType結構進行解碼,此函式支援記憶體分配選項

CryptEncodeObject對lpszStructType結構進行編碼

CyptEncodeObjectEx對lpszStructType結構進行編碼,此函式支援記憶體分配選項

1.4資料加密/解密函式

這些函式支援資料的加密/解密操作。

CryptEncrypt 和CryptDecrypt 要求在被呼叫前指定一個金鑰。

注:這個金鑰可以由CryptGenKey、CryptDeriveKey 或CryptImportKey 產生。建立密鑰時要指定加密演算法。

CryptSetKeyParam函式可以指定額外的加密引數。

CryptDecrypt使用指定加密金鑰來解密一段密文

CryptEncrypt使用指定加密金鑰來加密一段明文

CryptProtectData執行對DATA_BLOB結構的加密

CryptUnprotectData執行對DATA_BLOB結構的完整性驗證和解密

1.5雜湊和數字簽名函式

這些函式在應用程式中完成計算雜湊、建立和校驗數字簽名。

CryptCreateHash建立一個空雜湊物件

CryptDestoryHash銷燬一個雜湊物件

CryptDuplicateHash複製一個雜湊物件

CryptGetHashParam得到一個雜湊物件引數

CryptHashData對一塊資料進行雜湊,把它加到指定的雜湊物件中

CryptHashSessionKey對一個會話金鑰進行雜湊,把它加到指定的雜湊物件

CryptSetHashParam設定一個雜湊物件的引數

CryptSignHash對一個雜湊物件進行簽名

CryptVerifySignature校驗一個數字簽名

1.6函式詳解

1.6.1獲得CSP金鑰容器控制代碼

1.6.1.1 CryptAcquireContext

BOOL WINAPI CryptAcquireContext(

HCRYPTPROV *phProv,

LPCTSTR pszContainer,

LPCTSTR pszProvider,

DWORD dwProvType,

DWORD dwFlags

);

引數:

phProv[out] CSP控制代碼指標

pszContainer[in]金鑰容器名稱, 指向金鑰容器的字串指標。如果dwFlagsCRYPT_VERIFYCONTEXT,pszContainer必須為NULL。

pszProvider[in]指向CSP名稱的字串指標。如果為NULL,就使用卻省的CSP。

dwProvType[in]CSP型別。下表是就中常見的CSP型別

CSP型別

交換演算法

簽名演算法

對稱加密演算法

Hash演算法

PROV_RSA_FULL

RSA

RSA

RC2
RC4

MD5
SHA

PROV_RSA_SIG

none

RSA

none

MD5
SHA

PROV_RSA_SCHANNEL

RSA

RSA

RC4
DES
Triple DES

MD5
SHA

PROV_DSS

DSS

none

DSS

MD5
SHA

PROV_DSS_DH

DH

DSS

CYLINK_MEK

MD5
SHA

PROV_DH_SCHANNEL

DH

DSS

DES
Triple DES

MD5
SHA

PROV_FORTEZZA

KEA

DSS

Skipjack

SHA

PROV_MS_EXCHANGE

RSA

RSA

CAST

MD5

PROV_SSL

RSA

RSA

Varies

Varies

dwFlags[in]標誌:

CRYPT_VERIFYCONTEXT

指出應用程式不需要使用公鑰/私鑰對,如程式只執行雜湊和對稱加密。只有程式需要建立簽名和解密訊息時才需要訪問私鑰。

CRYPT_NEWKEYSET

使用指定的金鑰容器名稱建立一個新的金鑰容器。如果pszContainer為NULL,金鑰容器就使用卻省的名稱建立。

CRYPT_MACHINE_KEYSET

由此標誌建立的金鑰容器只能由建立者本人或有系統管理員身份的人使用。

CRYPT_DELETEKEYSET

刪除由pszContainer指定的金鑰容器。如果pszContainer 為NULL,預設名稱的容器就會被刪除。此容器裡的所有金鑰對也會被刪除。

CRYPT_SLIENT

應用程式要求CSP不顯示任何使用者介面。

說明:

這個函式是用來取得指定CSP金鑰容器控制代碼,以後的任何加密操作就是針對此CSP 句柄而言。函式首先查詢由dwProvType和pszProvider 指定的CSP,如果找到了CSP,函式就查詢由此CSP指定的金鑰容器。由適當的dwFlags 標誌,這個函式就可以建立和銷燬金鑰容器,如果不要求訪問私鑰的話,也可以提供對CSP臨時金鑰容器的訪問。

1.6.1.2 CryptReleaseContext

BOOL WINAPI CryptReleaseContext(

HCRYPTPROV hProv,

DWORD dwFlags

);

引數:

hProv[in]由CryptAcquireContext獲得的CSP 控制代碼。

dwFlags[in]保留。必須為0

說明:

此函式釋放CSP的控制代碼。對於每一次呼叫,CSP 的引用計數都減1。當引用計數為0時,CSP上下文就會被系統釋放變成無效控制代碼,以後針對此CSP 控制代碼的函式不再可用。

此函式並不銷燬金鑰容器或金鑰對。

//--------------------------------------------------------------------

HCRYPTPROV hCryptProv;

if (CryptAcquireContext(

hCryptProv, NULL,

MS_DEF_PROV,

PROV_RSA_FULL,

CRYPT_VERIFYCONTEXT))

CryptReleaseContext(hCryptProv, NULL);

1.6.2列舉CSP

4.1.6.2.1 CryptEnumProviders

BOOL WINAPI CryptEnumProviders(

DWORD dwIndex,

DWORD *pdwReserved,

DWORD dwFlags,

DWORD *pdwProvType,

LPTSTR pszProvName,

DWORD *pcbProvName

);

引數:

dwIndex[in]列舉下一個CSP的索引。

pdwReserved[in]保留。必須為NULL

dwFlags[in]保留。必須為NULL

pdwProvType[out]CSP的型別。

pszProvName[out]指向接收CSP名稱的緩衝區字串指標。此指標可為NULL,用來得到字元串的大小。

pcbProvName[in/out]指出pszProvName字串的大小。

說明:

此函式得到第一個或下一個可用的CSP。如果使用迴圈,就可以得到計算機上所有可用的CSP。 


1.6.3獲得CSP引數

4.1.6.3.1 CryptGetProvParam

BOOL WINAPI CryptGetProvParam(

HCRYPTPROV hProv,

DWORD dwParam,

BYTE *pbData,

DWORD *pdwDataLen,

DWORD dwFlags

);

引數:

hProv[in]CSP控制代碼。

dwParam[in]指定查詢的引數。

引數名

作用

PP_CONTAINER

指向金鑰名稱的字串

PP_ENUMALGS

不斷的讀出CSP支援的所有演算法

PP_ENUMALGS_EX

比PP_ENUMALGS獲得更多的演算法資訊

PP_ENUMCONTAINERS

不斷的讀出CSP支援的金鑰容器

PP_IMPTYPE

指出CSP怎樣實現的

PP_NAME

指向CSP名稱的字串

PP_VERSION

CSP的版本號

PP_KEYSIZE_INC

AT_SIGNATURE的位數

PP_KEYX_KEYSIZE_INC

AT_KEYEXCHANGE的位數

PP_KEYSET_SEC_DESCR 

金鑰的安全描述符

PP_UNIQUE_CONTAINER

當前金鑰容器的唯一名稱

PP_PROVTYPE

CSP型別

PP_USE_HARDWARE_RNG

指出硬體是否支援隨機數發生器

PP_KEYSPEC

返回CSP金鑰的資訊

pbData[out]指向接收資料的緩衝區指標。

pdwDataLen[in/out]指出pbData資料長度。

dwFlags[in]如果指定PP_ENUMCONTAINERS,就指定CRYPT_MACHINE_KEYSET。

說明:

此函式獲得CSP的各種引數。

[cpp] view plaincopyprint?
  1. //-----------------------------------------------------------------
  2. //
  3. HCRYPTPROV hCryptProv;  
  4. BYTE pbData[1000];  
  5. DWORD cbData;  
  6. //-------------------------------------------------------------------
  7. //預設CSP名稱
  8. cbData = 1000;  
  9. if(CryptGetProvParam(  
  10.    hCryptProv,  
  11.    PP_NAME,  
  12.    pbData,  
  13.    &cbData,  
  14.    0))  
  15. {  
  16.     printf("CryptGetProvParam succeeded.\n");  
  17.     printf("Provider name: %s\n", pbData);  
  18. }  
  19. else
  20. {  
  21.     printf("Error reading CSP name. \n");  
  22.     exit(1);  
  23. }  
  24. //--------------------------------------------------------------------
  25. cbData = 1000;  
  26. if(CryptGetProvParam(  
  27.    hCryptProv,  
  28.    PP_CONTAINER,  
  29.    pbData,  
  30.    &cbData,  
  31.    0))  
  32. {  
  33.     printf("CryptGetProvParam succeeded. \n");  
  34.     printf("Key Container name: %s\n", pbData);  
  35. }  
  36. else
  37. {  
  38.     printf("Error reading key container name. \n");  
  39.     exit(1);  
  40. }  
//-----------------------------------------------------------------

//

HCRYPTPROV hCryptProv;

BYTE pbData[1000];

DWORD cbData;

//-------------------------------------------------------------------

//預設CSP名稱

cbData = 1000;

if(CryptGetProvParam(

   hCryptProv,

   PP_NAME,

   pbData,

   &cbData,

   0))

{

	printf("CryptGetProvParam succeeded.\n");

	printf("Provider name: %s\n", pbData);

}

else

{

	printf("Error reading CSP name. \n");

	exit(1);

}

//--------------------------------------------------------------------

cbData = 1000;

if(CryptGetProvParam(

   hCryptProv,

   PP_CONTAINER,

   pbData,

   &cbData,

   0))

{

	printf("CryptGetProvParam succeeded. \n");

	printf("Key Container name: %s\n", pbData);

}

else

{

	printf("Error reading key container name. \n");

	exit(1);

}

4.1.6.4建立雜湊

4.1.6.4.1 CryptCreateHash

BOOL WINAPI CryptCreateHash(

HCRYPTPROV hProv,

ALG_ID Algid,

HCRYPTKEY hKey,

DWORD dwFlags,

HCRYPTHASH *phHash

);

引數:

hProv[in]CSP控制代碼

Algid[in]雜湊演算法的標示符。

hKey[in]如果雜湊演算法是金鑰雜湊,如HMAC或MAC 演算法,就用此金鑰控制代碼傳遞金鑰。對於非金鑰演算法,此引數為NULL

dwFlags[in]保留。必須為0

phHash[out]雜湊物件的控制代碼。

說明:

此函式初始化雜湊資料流。它建立並返回了一個CSP雜湊物件的控制代碼。此控制代碼由CryptHashData和CryptHashSessionKey來呼叫。

4.1.6.4.2 CryptHashData

BOOL WINAPI CryptHashData(

HCRYPTHASH hHash,

BYTE *pbData,

DWORD dwDataLen,

DWORD dwFlags

);

引數:

hHash[in]雜湊物件控制代碼

pbData[in]指向要加入到雜湊物件的資料指標

dwDataLen[in]資料長度

dwFlags[in]標誌

CRYPT_USERDATA所有微軟CSP都忽略此引數。所有其他CSP 都不能忽略此引數,如果置此引數,CSP提示使用者直接資料資料。

說明:

此函式把一段資料加入到指定的雜湊物件中去。

4.1.6.4.3 CryptGetHashParam

BOOL WINAPI CryptGetHashParam(

HCRYPTHASH hHash,

DWORD dwParam,

BYTE *pbData,

DWORD *pdwDataLen,

DWORD dwFlags

);

引數:

hHash[in]雜湊物件的控制代碼

dwParam[in]查詢型別。可以是下列:

引數名稱

作用

HP_ALGID

雜湊演算法

HP_HASHSIZE

雜湊值長度

HP_HASHVAL

雜湊值,由hHash指定的雜湊值或者訊息雜湊

說明:

此函式得到指定雜湊物件的資料。

4.1.6.4.4 CryptDestroyHash

BOOL WINAPI CryptDestroyHash(

HCRYPTHASH hHash

);

引數:

hHash[in]要銷燬的雜湊物件控制代碼

說明:

此函式銷燬由hHash指定的雜湊物件。當一個雜湊物件被銷燬後,它對程式來說不可用。

[cpp] view plaincopyprint?
  1. …  
  2. HCRYPTHASH hCryptHash;  
  3. if (CryptCreateHash(  
  4. hCryptProv,  
  5. CALG_MD5,  
  6. 0,  
  7. 0,  
  8. &hCryptHash  
  9. ))  
  10. CryptDestroyHash(hCryptHash);  
  11. …  
…

HCRYPTHASH hCryptHash;

if (CryptCreateHash(

hCryptProv,

CALG_MD5,

0,

0,

&hCryptHash

))

CryptDestroyHash(hCryptHash);

…

4.1.6.5派生金鑰

4.1.6.5.1 CryptDeriveKey

BOOL WINAPI CryptDeriveKey(

HCRYPTPROV hProv,

ALG_ID Algid,

HCRYPTHASH hBaseData,

DWORD dwFlags,

HCRYPTKEY *phKey

);

引數:

hProv[in]CSP控制代碼

Algid[in]要產生金鑰的對稱加密演算法

hBaseData[in]雜湊物件的控制代碼

dwFlags[in]指定金鑰的型別

引數

作用

CRYPT_CREATE_SALT

由雜湊值產生一個會話金鑰,有一些需要補位。如果用此標誌,金鑰將會賦予一個鹽值

CRYPT_EXPORTABLE

如果置此標誌,金鑰就可以用CryptExportKey函式匯出。

CRYPT_NO_SALT

如果置此標誌,表示40位的金鑰不需要分配鹽值。

CRYPT_UPDATE_KEY

有些CSP從多個雜湊值中派生會話金鑰。如果這種情況,CryptDeriveKey需要多次呼叫

phKey[in/out]金鑰的控制代碼

說明:

此函式從一基本資料值中派生會話金鑰。函式保證當CSP和演算法相同時,從相同基本資料值中產生的金鑰是唯一的。