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得到的控制代碼
CryptSetProvider和CryptSetProviderEx為指定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]金鑰容器名稱, 指向金鑰容器的字串指標。如果dwFlags為CRYPT_VERIFYCONTEXT,pszContainer必須為NULL。
pszProvider[in]指向CSP名稱的字串指標。如果為NULL,就使用卻省的CSP。
dwProvType[in]CSP型別。下表是就中常見的CSP型別
CSP型別 |
交換演算法 |
簽名演算法 |
對稱加密演算法 |
Hash演算法 |
PROV_RSA_FULL |
RSA |
RSA |
RC2 |
MD5 |
PROV_RSA_SIG |
none |
RSA |
none |
MD5 |
PROV_RSA_SCHANNEL |
RSA |
RSA |
RC4 |
MD5 |
PROV_DSS |
DSS |
none |
DSS |
MD5 |
PROV_DSS_DH |
DH |
DSS |
CYLINK_MEK |
MD5 |
PROV_DH_SCHANNEL |
DH |
DSS |
DES |
MD5 |
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?- //-----------------------------------------------------------------
- //
- 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);
- }
//-----------------------------------------------------------------
//
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?- …
- HCRYPTHASH hCryptHash;
- if (CryptCreateHash(
- hCryptProv,
- CALG_MD5,
- 0,
- 0,
- &hCryptHash
- ))
- CryptDestroyHash(hCryptHash);
- …
…
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和演算法相同時,從相同基本資料值中產生的金鑰是唯一的。