C++ CNG NCrypt问题:无法从密钥存储提供程序打开持久化密钥
问题分析与解决方案
核心问题:创建的持久化密钥被立即删除
你的第一个程序中,Cleanup()函数调用了NCryptDeleteKey(hKey, 0)——这个函数会永久删除KSP中的持久化密钥。也就是说,你刚创建并完成初始化的密钥,在程序退出前就被彻底删掉了,第二个程序自然无法找到它。
你需要修改Cleanup()函数,移除对NCryptDeleteKey的调用,仅释放密钥句柄而非删除密钥本身:
void Cleanup() { if (hHashAlg) BCryptCloseAlgorithmProvider(hHashAlg, 0); if (hSignAlg) BCryptCloseAlgorithmProvider(hSignAlg, 0); if (hHash) BCryptDestroyHash(hHash); if (pbHashObject) HeapFree(GetProcessHeap(), 0, pbHashObject); if (pbHash) HeapFree(GetProcessHeap(), 0, pbHash); if (pbSignature) HeapFree(GetProcessHeap(), 0, pbSignature); // 移除删除密钥的代码,改为仅释放句柄 if (hKey) NCryptFreeObject(hKey); if (hProv) NCryptFreeObject(hProv); }
其他需要验证的细节
- 哈希变量未初始化:第一个程序中
pbHash和cbHash未赋值就传入NCryptSignHash,会导致未定义行为,需确保签名前已正确计算目标哈希值并初始化这两个变量。 - 密钥访问权限:如果两个程序运行在不同用户上下文(比如一个用管理员权限、一个用普通用户),可能因权限问题找不到密钥。创建密钥时可添加
NCRYPT_MACHINE_KEY_FLAG参数(需管理员权限),创建机器级密钥,让不同用户上下文都能访问:if (FAILED(secStatus = NCryptCreatePersistedKey(hProv, &hKey, NCRYPT_ECDSA_P256_ALGORITHM, KEY_NAME, 0, NCRYPT_MACHINE_KEY_FLAG))) { Cleanup(); return {}; }
内容的提问来源于stack exchange,提问作者Alexandr
相关产品推荐
相关产品推荐

