CryptAcquireContext() 失败并显示 return 代码 0x8009000B NTE_BAD_KEY_STATE - 但用户密码未更改

CryptAcquireContext() fails with return code 0x8009000B NTE_BAD_KEY_STATE - But user password has not changed

我公司有一个用vb6编译的程序,在使用软件之前需要验证加密的许可证代码。最近有客户来电说license code验证失败,程序被锁。经过一些调查,我发现代码在调用 CryptAcquireContext 时失败,错误代码为 0x8009000B (NTE_BAD_KEY_STATE)。 CryptAcquireContext 的 Microsoft 支持页面声明此错误意味着 "the user password has changed since the private keys were encrypted"

客户最近电脑出现问题,新装了一个固态硬盘,重新安装了Win7。但是,他确定他的用户密码没有更改,服务器密码也没有更改(用户计算机包含指向服务器上可执行文件的快捷方式,没有其他用户遇到此问题)。在搜索一些 Microsoft 论坛后,很明显其他人也遇到过此错误(也有相同的密码),并且在每种情况下它都是高度偶发的,并且通常对于使用相同程序的机器系统中的一台计算机是唯一的。我审查的每个案例都进入了死胡同; Microsoft 对这个错误毫无帮助,我已经用尽了我对 google.

的研究能力

这是失败的代码片段。对于我在这个特定领域缺乏知识,我深表歉意,我们的程序用于 encrypt/decryption 的 class 来自一个开源项目(cCrypt Class 模块 - Kevin Wilson)

If CryptAcquireContext(lngCryptProv, 0, p_CSP_String, p_CSP_Type, 0) = 0 Then

    ' If there is no default key container then create one using Flags field'

    CheckGetLastError Err.LastDllError, Return_ErrNum, Return_ErrDesc, "CryptAcquireContext", False

    If Return_ErrNum = -2146893802 Then
      Return_ErrNum = 0
      Return_ErrDesc = ""

      If CryptAcquireContext(lngCryptProv, 0, p_CSP_String, p_CSP_Type, CRYPT_NEWKEYSET) = 0 Then

        CheckGetLastError Err.LastDllError, Return_ErrNum, Return_ErrDesc, "CryptAcquireContext", False
        Exit Function

      End If
    Else
      Exit Function
    End If
  End If

第一次调用 CryptAcquireContext 失败。我尝试绕过第一个调用并直接转到带有标志 CRYPT_NEWKEYSET 的第二个调用,但该调用也失败了。

如果有人能阐明这个问题,我将不胜感激。提前致谢!

PS。这是 Microsoft 论坛上的一个很好的例子,有人 运行 在没有更改密码的情况下遇到同样的问题,Microsoft 代表最终停止回复(可以为您提供一些额外信息):

https://groups.google.com/forum/#!topic/microsoft.public.platformsdk.security/XhzsN9HQWjk

我通过将 CryptAcquireContext (0) 中的最后一个参数更改为 CRYPT_VERIFYCONTEXT 标志来解决此问题。现在似乎工作正常!