基本概述
CryptAcquireContext是Windows加密API(CryptoAPI)中的核心函数,主要作用是获取一个加密服务提供程序(CSP)的上下文句柄。这个句柄是后续所有加密操作(如创建 / 打开密钥、加密 / 解密数据、数字签名 / 验证等)的基础,相当于 “登录” 到系统的加密服务,拿到操作权限。
简单来说:没有这个函数获取的上下文句柄,你无法使用 Windows 系统提供的加密功能(比如使用RSA加密、生成数字证书等)。
CryptReleaseContext是Windows CryptoAPI中用于释放通过CryptAcquireContext获取的CSP上下文句柄(HCRYPTPROV)的专用函数。
简单来说,它的作用就是 “归还” 你之前从系统申请的加密服务资源,相当于加密操作完成后的 “注销登录”,是避免内存 / 资源泄漏的核心步骤。
只要调用CryptAcquireContext成功获取了HCRYPTPROV句柄,就必须调用这个函数释放,否则会导致进程持有的系统加密资源无法回收。
基本语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| BOOL CryptAcquireContextA( [out] HCRYPTPROV *phProv, [in] LPCSTR szContainer, [in] LPCSTR szProvider, [in] DWORD dwProvType, [in] DWORD dwFlags );
BOOL CryptAcquireContextA( [out] HCRYPTPROV *phProv, [in] LPCSTR szContainer, [in] LPCSTR szProvider, [in] DWORD dwProvType, [in] DWORD dwFlags );
BOOL CryptReleaseContext( [in] HCRYPTPROV hProv, [in] DWORD dwFlags );
|
数据类型
HCRYPTPROV:
HCRYPTPROV本质上是Windows CryptoAPI中的一个句柄类型(Handle),完整拼写是Handle to a CRYPTOGRAPHIC PROVIDER,翻译过来就是 “加密服务提供程序(CSP)的句柄”。
1 2
| typedef unsigned __int64 ULONG_PTR, *PULONG_PTR; typedef ULONG_PTR HCRYPTPROV;
|
在32位系统中,ULONG_PTR实际定义为unsigned int(4 字节),和32位指针长度匹配:64位系统中才是unsigned __int64(8 字节)。
HCRYPTPROV的长度和系统指针一致,能安全存储系统内核返回的句柄值(64位系统的句柄是8字节,若用32位unsigned long存储会截断)。
简单示例
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
| #include <windows.h> #include <wincrypt.h> #include <stdio.h>
#pragma comment(lib, "advapi32.lib")
int main() { HCRYPTPROV hProv = NULL;
BOOL bAcquireSuccess = CryptAcquireContext( &hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT );
if (!bAcquireSuccess) { DWORD dwAcquireErr = GetLastError(); printf("CryptAcquireContext 失败,错误码:%lu\n", dwAcquireErr); return 1; } printf("成功获取CSP句柄:%p\n", hProv);
BYTE randomBuf[16] = {0}; BOOL bRandomSuccess = CryptGenRandom(hProv, sizeof(randomBuf), randomBuf); if (bRandomSuccess) { printf("生成随机数:"); for (int i = 0; i < 16; i++) { printf("%02X ", randomBuf[i]); } printf("\n"); } else { printf("CryptGenRandom 失败,错误码:%lu\n", GetLastError()); }
BOOL bReleaseSuccess = CryptReleaseContext(hProv, 0); if (bReleaseSuccess) { printf("句柄释放成功\n"); hProv = NULL; } else { DWORD dwReleaseErr = GetLastError(); printf("CryptReleaseContext 失败,错误码:%lu\n", dwReleaseErr); }
return 0; }
|