CryptCreateHash
基本概念
CryptCreateHash属于Windows CryptoAPI(Advapi32.dll),作用是初始化一个哈希计算上下文(哈希对象),后续可通过CryptHashData向该对象添加数据,最终通过 CryptGetHashParam获取哈希结果。
基本语法
1 2 3 4 5 6 7
| BOOL CryptCreateHash( [in] HCRYPTPROV hProv, [in] ALG_ID Algid, [in] HCRYPTKEY hKey, [in] DWORD dwFlags, [out] HCRYPTHASH *phHash );
|
数据类型
ALG_ID:
1
| typedef unsigned int ALG_ID;
|
ALG_ID本质是无符号整数,专门用来标识Windows CryptoAPI中的加密 / 哈希算法.
1 2 3 4 5 6 7
| ALG_ID 常量 对应的整数值 算法类型 用途 CALG_MD5 0x00008003 哈希算法 MD5 哈希计算 CALG_SHA1 0x00008004 哈希算法 SHA1 哈希计算 CALG_SHA_256 0x0000800C 哈希算法 SHA256 哈希计算 CALG_SHA_512 0x0000800D 哈希算法 SHA512 哈希计算 CALG_AES_256 0x00006610 对称加密算法 AES-256 加密 / 解密 CALG_HMAC 0x00008009 密钥哈希算法 HMAC 验证(需配合密钥)
|
HCRYPTKEY:
1
| typedef ULONG_PTR HCRYPTKEY;
|
是Windows CryptoAPI中对加密密钥句柄的类型定义,核心作用是把ULONG_PTR类型重命名为HCRYPTKEY,用来标识一个加密 / 解密密钥的上下文对象。
HCRYPTHASH:
1
| typedef ULONG_PTR HCRYPTHASH;
|
是Windows CryptoAPI中对哈希对象句柄的类型定义,核心作用是将ULONG_PTR类型重命名为HCRYPTHASH,用来标识一个哈希计算的上下文对象。
CryptHashData
基本概念
CryptHashData的作用是将一段数据(字符串、文件内容、二进制流等)写入到HCRYPTHASH哈希对象中,可多次调用该函数向同一个哈希对象追加数据,最终计算所有数据的整体哈希值。
基本语法
1 2 3 4 5 6
| BOOL CryptHashData( [in] HCRYPTHASH hHash, [in] const BYTE *pbData, [in] DWORD dwDataLen, [in] DWORD dwFlags );
|
返回值
成功:返回TRUE(非 0);
失败:返回FALSE(0),可通过GetLastError()获取具体错误码(如NTE_INVALID_HANDLE表示哈希句柄无效)。
CryptGetHashParam
基本概念
CryptGetHashParam的核心作用是 “读取哈希对象的参数”,最常用的场景是获取最终计算出的哈希值(二进制形式),也可查询哈希算法的相关信息(如哈希值长度、算法 ID 等)。
基本语法
1 2 3 4 5 6 7
| BOOL CryptGetHashParam( [in] HCRYPTHASH hHash, [in] DWORD dwParam, [out] BYTE *pbData, [in, out] DWORD *pdwDataLen, [in] DWORD dwFlags );
|
返回值
成功:返回TRUE(非 0);
失败:返回FALSE(0),可通过GetLastError()获取错误码(如ERROR_MORE_DATA表示缓冲区长度不足)。
简单示例
计算SHA256哈希
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| #include <windows.h> #include <wincrypt.h> #include <stdio.h> #include <string.h>
#pragma comment(lib, "Advapi32.lib")
int main() { HCRYPTPROV hProv = NULL; HCRYPTHASH hHash = NULL; const char* input = "Hello World"; BYTE hashResult[32] = {0}; DWORD hashLen = sizeof(hashResult); DWORD i;
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { printf("CSP获取失败,错误码: %lu\n", GetLastError()); return 1; }
if (!CryptCreateHash(hProv, CALG_SHA_256, NULL, 0, &hHash)) { printf("创建哈希对象失败,错误码: %lu\n", GetLastError()); CryptReleaseContext(hProv, 0); return 1; }
if (!CryptHashData(hHash, (const BYTE*)input, strlen(input), 0)) { printf("填充哈希数据失败,错误码: %lu\n", GetLastError()); CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); return 1; }
if (!CryptGetHashParam(hHash, HP_HASHVAL, hashResult, &hashLen, 0)) { printf("获取哈希值失败,错误码: %lu\n", GetLastError()); CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); return 1; }
printf("输入字符串: %s\n", input); printf("SHA256哈希值: "); for (i = 0; i < hashLen; i++) { printf("%02x", hashResult[i]); } printf("\n");
CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0);
return 0; }
|
资源释放:创建的hHash必须通过CryptDestroyHash释放,hProv需通过CryptReleaseContext释放,否则会导致资源泄漏。