You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 16:45:33