| 演算法 | CALG 常數 | 輸出長度 | 現代建議 |
| MD5 | CALG_MD5 | 128 bits | 已脆弱,僅用於非安全校驗 |
| SHA-1 | CALG_SHA1 | 160 bits | 理論碰撞風險,漸淘汰 |
| SHA-256 | CALG_SHA_256 | 256 bits | 推薦標準 |
| SHA-384 | CALG_SHA_384 | 384 bits | 高安全需求 |
| SHA-512 | CALG_SHA_512 | 512 bits | 最高安全需求 |
雜湊計算流程
HCRYPTHASH hHash;
CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
// 分塊更新 (大檔案/串流)
BYTE buffer[4096];
DWORD read;
while (ReadFile(hFile, buffer, sizeof(buffer), &read, NULL) && read > 0) {
CryptHashData(hHash, buffer, read, 0);
}
// 取得雜湊值
BYTE hash[32]; // SHA-256 = 32 bytes
DWORD hashLen = 32;
CryptGetHashParam(hHash, HP_HASHVAL, hash, &hashLen, 0);
CryptDestroyHash(hHash);
五、數位簽章完整流程
簽章端 (持有私鑰)
// 1. 計算資料雜湊
CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
CryptHashData(hHash, data, dataLen, 0);
// 2. 使用私鑰 (AT_SIGNATURE) 簽署雜湊
BYTE sig[256]; // 視金鑰長度而定
DWORD sigLen = sizeof(sig);
CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, sig, &sigLen);
// 3. 輸出:原始資料 + 簽章 + 演算法標識
驗證端 (持有公鑰)
// 1. 取得對方公開金鑰 (從憑證、金鑰 Blob 或 CSP 匯入)
HCRYPTKEY hPubKey;
CryptImportKey(hProv, pubKeyBlob, blobLen, 0, 0, &hPubKey);
// 2. 計算相同資料雜湊
CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash);
CryptHashData(hHash, data, dataLen, 0);
// 3. 驗證簽章
if (CryptVerifySignature(hHash, sig, sigLen, hPubKey, NULL, 0)) {
printf("簽章驗證通過:資料完整且來源可信\n");
} else {
printf("驗證失敗: 0x%08X\n", GetLastError());
// NTE_BAD_SIGNATURE = 簽章不符 (資料被竄改或非持有私鑰者簽署)
}
CryptDestroyKey(hPubKey);
CryptDestroyHash(hHash);
六、Session Key 加密傳輸 (混合加密)
// 發送端
HCRYPTKEY hSessionKey;
CryptGenKey(hProv, CALG_AES_256, CRYPT_EXPORTABLE, &hSessionKey);
// 用對方公鑰加密 Session Key
BYTE keyBlob[1024];
DWORD blobLen = sizeof(keyBlob);
CryptExportKey(hSessionKey, hRecipientPubKey, SIMPLEBLOB, 0, keyBlob, &blobLen);
// 傳送:keyBlob + 用 Session Key 加密的資料
// 接收端
HCRYPTKEY hImportedSessionKey;
CryptImportKey(hProv, keyBlob, blobLen, hMyPrivateKey, 0, &hImportedSessionKey);
// 現在可用 hImportedSessionKey 解密資料
七、最佳實踐與遷移建議
⚠ CryptoAPI 狀態
- Windows 2000 時代核心 API,已標記為 Legacy
- 新專案強烈建議使用 CNG (Cryptography Next Generation):
BCrypt*/NCrypt* API
- CNG 支援現代演算法 (AES-GCM, ChaCha20-Poly1305, ECDSA, Ed25519)、硬體金鑰儲存 (TPM, KSP)、更佳效能與安全性
遷移對照
| CryptoAPI | CNG |
| HCRYPTPROV | BCRYPT_ALG_HANDLE / NCRYPT_KEY_HANDLE |
| CryptAcquireContext | BCryptOpenAlgorithmProvider / NCryptOpenStorageProvider |
| CryptGenKey | BCryptGenerateSymmetricKey / NCryptCreatePersistedKey |
| CryptEncrypt/Decrypt | BCryptEncrypt/Decrypt |
| CryptSignHash/VerifySignature | BCryptSignHash/VerifySignature |
結語
CryptoAPI 奠定了 Windows 加密基礎設施,理解其金鑰容器、雜湊、簽章、混合加密流程對維護舊系統至關重要。新開發專案請全面採用 CNG,享受現代密碼學標準與硬體加速優勢。
- 上一篇文章: Linux 共用函式庫 (.so) 開發完整指南:建立、載入與實戰範例
- 下一篇文章: Microsoft CryptoAPI 加密技術入門(一):架構、加密模式與 CSP 核心概念
Copyright ©
程式碼之家 All Rights Reserved