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

| | August 4, 2015

My company has a program compiled in vb6 which requires an encrypted license code to be validated before the software can be used. Recently, a client called saying the license code was failing to validate and the program was locked. After some investigation, I discovered the code was failing on a call to CryptAcquireContext with an error code 0x8009000B (NTE_BAD_KEY_STATE). The Microsoft support page for CryptAcquireContext states that this error means “the user password has changed since the private keys were encrypted”

The client recently had problems with his computer, so he installed a new solid state drive and re-installed Win7. However, he is sure that his user password has not changed, nor has the Server password (User computers contain a shortcut that points to an executable on the server, no other users are experiencing this problem). After searching through some Microsoft forums, it is clear that others have experienced this error (also having the same password), and that in every case it is highly sporadic and often unique to one computer in a system of machines using the same program. Every case I reviewed resulted in a dead end; Microsoft has been very unhelpful with this bug and I have exhausted my research capabilities on google.

Here is the code snippet that is failing. I apologize for my lack of knowledge in this particular area, the class our program uses for encrypt/decryption comes from an open source project (cCrypt Class Module – 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

It is the first call to CryptAcquireContext that is failing. I tried bypassing the first call and going straight to the second one with the flag CRYPT_NEWKEYSET, but that call failed as well.

If anyone can shed some light on this issue, I would greatly appreciate it. Thanks in advance!

PS. Here is a great example on a Microsoft forum of someone running into the same problem absent of a password change, and the Microsoft representative eventually stops replying (could provide some extra info for you) :

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

One Response to “CryptAcquireContext() fails with return code 0x8009000B NTE_BAD_KEY_STATE – But user password has not changed”

  1. I fixed this issue by changing the last argument in CryptAcquireContext (0) to the CRYPT_VERIFYCONTEXT flag. Seems to be working fine now!

Leave a Reply