locked
CryptSignHash failed after installing Windows 10 1909 build RRS feed

  • Question

  • Hello,

    An application of us is no more working after a Windows Update.

    The application is calling API function CryptSignHash. When using Windows 10 1709 build, there is no issue. Just after updating to Windows 10 1909 build, call to CryptSignHash failed with error 0x80090006 (NTE_BAD_SIGNATURE).

    We are using a certificat located in a HP EliteBook 1040G6 TPM device. The CSP used is "Microsoft Base Smart Card Crypto Provider".

    With 1709 build, we are parsing container \\.\Microsoft Virtual Smart Card 0\te-VSC-Template-e644dad6-69d8-4d8-37240

    With 1909 build, we are parsing container \\.\Microsoft Virtual Smart Card 1\te-VSC-Template-fbe6697d-524e-40f-07224

    Is there a way for getting logs from the used CSP ?

    Thank in advance for any help

    Regards.

    Eric

    Tuesday, January 7, 2020 10:21 AM

All replies

  • Hello ErBod,

    CryptSignHash API is used to create the signature instead of using signature. NTE_BAD_SIGNATURE error is more like from, for example, CryptVerifySignature API. Could you show some related code?

    There are several reasons for NTE_BAD_SIGNATURE error:

    1. This might be because the data itself has changed, the description string did not match, or the wrong public key was specified by hPubKey.
    2. This error can also be returned if the hashing or signature algorithms do not match the ones used to create the signature.
    3. If you generate a signature by using the .NET Framework APIs and try to verify it by using the CryptVerifySignature function, the function will fail and GetLastError will return NTE_BAD_SIGNATURE. This is due to the different byte orders between the native Win32 API and the .NET Framework API.

    Could you show a mini, complete and reproducible sample so I can do a further investigation.

    Best regards,

    Rita


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, January 8, 2020 3:16 AM
  • Hello Rita,

    The application is generating a signature from a hash instead of the signature from a message. It is using a private key from a certificate stored in a virtual smartcard.

    As I wrote earlier, our application is reported not working anymore with Windows 10 1909 build update. But we have also reports it is still working.

    I first provide the main API calls. I am preparing a code sample. Our application is C++ code based.

    Here are the main calls :
    1) looking for a container in the smartcard

    CryptAcquireContext&m_hCryptProvider, m_szContainerName, m_szCSPName, PROV_RSA_FULL, m_AcquireFlag)    
    CryptGetProvParam(m_hCryptProvider, PP_ENUMCONTAINERS, NULL, &dwContainerSize, enumContainers)
    CryptGetProvParam(m_hCryptProvider, PP_ENUMCONTAINERS, pContainer, &dwContainerSize, enumContainers)

    2) looking for a certificate in the container

    wsprintf(szContainerName,"%s%s",m_szContainerName,pContainer);
    CryptAcquireContext(&m_hCertOnTokenProv,szContainerName,m_szCSPName,PROV_RSA_FULL,m_AcquireFlag)
    CryptGetUserKey(m_hCertOnTokenProv, rgdwKeys[0], &hKey)
    CryptGetKeyParam(hKey, KP_CERTIFICATE, NULL, &length, 0)
    p = (LPBYTE)malloc(length);
    CryptGetKeyParam(hKey, KP_CERTIFICATE, p, &length, 0)

    3) Once the certificate is found, creating a hash

    CryptCreateHash(m_hCertOnTokenProv, CALG_SHA_256, NULL, NULL, &m_hCryptHash)

    4) retrieving the signature length

    CryptSignHash(m_hCryptHash, AT_KEYEXCHANGE, NULL, CRYPT_NOHASHOID, NULL, (DWORD*)signature_length)

    5) setting the hash to be signed

    CryptSetHashParam(m_hCryptHash, HP_HASHVAL, (BYTE*)hash2beSigned, 0)

    6) generating the signature

    CryptSignHash(m_hCryptHash, AT_KEYEXCHANGE, NULL, 0, m_signature, (DWORD*)signature_length)

    Regards.

    Eric


    • Edited by ErBod Thursday, January 9, 2020 8:49 AM
    Wednesday, January 8, 2020 5:33 PM
  • Hi Eric,

    Thanks for the detailed info for this issue.

    Would you mind help double confirm that the error message 0x80090006 (NTE_BAD_SIGNATURE) coming from CryptSignHash API? Because as Rita already explain the error more relative the signature relative operation.

    And the CryptSignHash API is deprecated. New and existing software should start using Cryptography Next Generation APIs. Microsoft may remove this API in future releases. Does Cryptography Next Generation APIs works for the your scenario? Below are some helpful documents for your reference:

    Creating a Hash with CNG

    Signing Data with CNG

    Regards & Fei


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.



    Thursday, January 9, 2020 9:31 AM
  • Hello Fei,

    I confirm that CryptSignHash is returning 0x80090006.

    Our application does not support CNG API yet. I am working on this issue.

    Regards.

    Eric

    Friday, January 10, 2020 2:26 PM
  • Fei,

    Thank you for the links about signing. Do you have documents for how reading certificates in a smartcard ?

    Regards.

    Eric
    Friday, January 10, 2020 2:48 PM
  • Hi Eric,

    For persisted keys, you use the key storage functions to load a key storage provider, and then create or load the keys. You can also use these functions to create or load ephemeral keys by passing NULL for any container names. For more information about the key storage functions, see CNG Key Storage Functions. More programming with CNG, you can refer to the document below:

    Typical CNG Programming

    For the details steps of reading certificates using CNG, you can refer below:

    1. Open the smart card key storage provider via NCryptOpenStorageProvider

    2. Open the keys in the smart card key storage provider via NCryptOpenKey 

    Regards & Fei


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, January 13, 2020 8:23 AM
  • Hello Fei,

    What are the differences between BFunction and NFunction ? For example, I can use
    BCryptSignHash or NCryptSignHash. The parameters seem the same. As bcrypt.h is included in ncrypt.h, I think bCryptSignHash may be a lower level API.

    Regards.

    Eric


    Tuesday, January 14, 2020 9:49 AM
  • Hi Eric,

    The BCryptSignHash is CNG cryptographic primitive functions, and the NCryptSignHash belongs to CNG Key Storage Functions which use to perform CNG key storage operations.

    Below illustrations show the difference between them:

    Cryptographic Primitives

    Key Storage Architecture:

    So if you are developing the keys store in the Key Storage Provider, the Key Storage APIs are recommend.

    Regards & Fei


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, January 16, 2020 8:36 AM