none
ECDsaCng with smart card -> CryptographicException RRS feed

  • Question

  • When I run following code, I get CryptographicException.

             using (c1 = CngKey.Open("ecc_test_card21_384", CngProvider.MicrosoftSmartCardKeyStorageProvider, CngKeyOpenOptions.UserKey))
                {
                    using (ECDsaCng ecsdKey = new ECDsaCng(c1))
                    {
                        ecsdKey.SignData(dataX);
                    }
                }
    

    System.Security.Cryptography.CryptographicException was unhandled
      Message=The parameter is incorrect.

      Source=System.Core
      StackTrace:
           v System.Security.Cryptography.NCryptNative.GetProperty(SafeNCryptHandle ncryptObject, String propertyName, CngPropertyOptions propertyOptions, Boolean& foundProperty)
           v System.Security.Cryptography.CngKey.get_IsEphemeral()
           v System.Security.Cryptography.ECDsaCng..ctor(CngKey key)
      InnerException:

    Using C not C# with following sequence works fine

    NCryptOpenStorageProvider

    NCryptOpenKey

    NCryptSignHash

    Is there a solution how to use ECDsaCng with smart card?


    Lukas

    Friday, September 14, 2012 10:59 AM

All replies

  • I assume the open statement is working and you are getting the error on the SignData() method.

    You are probably getting the error because of dataX.  I would need to know more about the way this variable is obtained in the C# and C code.   You may be reading the key in 7 bit mode rather than 8 bith mode from a file.  Check you stream encoding method.


    jdweng

    Friday, September 14, 2012 1:46 PM
  • Hi Lukas,

    Welcome to the MSDN Forum.

    How about your application now?

    Does this issue resolved?

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, September 19, 2012 8:54 AM
    Moderator
  • hi,

    issue is not resolved, because exception is thrown within ECDsaCng constructor (and I dn't know why).

    You can see in this line:

       v System.Security.Cryptography.ECDsaCng..ctor(CngKey key),

       when is called get_IsEphemeral()

    According to Joel, ecsdKey.SignData(dataX) si not called at all.

    code in C:

    	if(FAILED(secStatus = NCryptOpenStorageProvider(
                                                    	&hProv, 
                                                    	provider, 
                                                    	0)))
        {
            wprintf(L"**** Error 0x%x returned by NCryptOpenStorageProvider\n", secStatus);
            goto Cleanup;
        }
    
    
    	if(FAILED(secStatus = NCryptOpenKey(
                                                    hProv,
    						&hPrivKey,
                                                    keyName,
                                                    0,
                                                    0)))
        {
            wprintf(L"**** Error 0x%x returned by NCryptOpenKey\n", secStatus);
            goto Cleanup;
        }
    
        //sign the hash
        if(FAILED(secStatus = NCryptSignHash(
    					hPrivKey,
                                    	NULL,
                                        	pbHash,
                                        	cbHash,
                                        	NULL,
                                        	0,
                                        	&cbSignature,
                                        	0)))
        {
            wprintf(L"**** Error 0x%x returned by NCryptNCryptSignHash\n", secStatus);
            goto Cleanup;
        }
    
        //allocate the signature buffer
        pbSignature = (PBYTE)HeapAlloc (GetProcessHeap (), 0, cbSignature);
        if(NULL == pbSignature)
        {
            wprintf(L"**** memory allocation failed\n");
            goto Cleanup;
        }
    
        if(FAILED(secStatus = NCryptSignHash(
    					   hPrivKey,
    	                                   NULL,
            	                           pbHash,
                    	                   cbHash,
                            	           pbSignature,
                                    	   cbSignature,
    	                                   &cbSignature,
            	                           0)))
        {
            wprintf(L"**** Error 0x%x returned by NCryptNCryptSignHash\n", secStatus);
            goto Cleanup;
        }
    
    


    Lukas

    Tuesday, September 25, 2012 1:00 PM
  • The problem is how the variables are declared.  the definition of the variables are not show for both the C# and C code so it is hard to determine exactly where the problem is.  You should be getting the same key (c1) returned from the card in both the C# and c code.  In th ec# code the variable c1 should be declared as either a byte[] or a stream with encoding type Encoding.UTF8

    jdweng

    Tuesday, September 25, 2012 2:06 PM
  • The provider is Microsoft Smart Card Key Storage Provider, so I allways get object handle...

    In C# code:

    key is System.Security.Cryptography.CngKey object.

                byte[] data = new byte[] {  
                    0x04, 0x87, 0xec, 0x66, 0xa8, 0xbf, 0x17, 0xa6
                };
    
    
                CngKey c = CngKey.Open("ecc_test_256_20120925", CngProvider.MicrosoftSmartCardKeyStorageProvider);
                using (ECDsaCng ecsdKey = new ECDsaCng(c))
                {
                    ecsdKey.HashAlgorithm = CngAlgorithm.Sha256;
                    ecsdKey.SignData(data, 0, data.Length);
                }
    
    In C code:

    handles and parameters are obvious from function's declarations.

    LPCWSTR provider = MS_SMART_CARD_KEY_STORAGE_PROVIDER;
    
    LPCWSTR sigId = BCRYPT_ECDSA_P256_ALGORITHM;
    PBYTE pbHash = NULL;
    DWORD cbHash = 0;
    LPCWSTR keyName = L"ecc_test_256_20120925";
    NCRYPT_PROV_HANDLE      hProv           = NULL;
    NCRYPT_KEY_HANDLE       hPrivKey            = NULL;
    BCRYPT_KEY_HANDLE       hTmpKey         = NULL;
    SECURITY_STATUS         secStatus       = ERROR_SUCCESS;
    BCRYPT_ALG_HANDLE       hSignAlg        = NULL;
    NTSTATUS                status          = STATUS_UNSUCCESSFUL;
    DWORD                   cbData          = 0,
                                cbBlob          = 0,
                                cbSignature     = 0,
                                cbHashObject    = 0;
    PBYTE                   pbBlob          = NULL,
                                pbSignature     = NULL;
    


    Lukas

    Tuesday, September 25, 2012 3:16 PM
  • I haven't worked with SHA algorithm for a while.  Read the Wiki page below

    http://en.wikipedia.org/wiki/Secure_Hash_Algorithm

    You have a key which with 8 words (64 bit).  The Wiki page says 64 bit is SHA-512 while your code is using Sha 256.  I believe the key size is suppose to be the same size as the block size.


    jdweng

    Tuesday, September 25, 2012 4:54 PM
  • hi,

    thank for your effort but I need answer from somebody who understand ECDSA and smart cards, especially somebody who knows something about ECDsaCng implementation with MicrosoftSmartCardKeyStorageProvider.


    Lukas

    Wednesday, September 26, 2012 11:49 AM
  • From a support perspective this is really beyond what we can do here in the forums. If you cannot determine your answer here or on your own, consider opening a support case with us. Visit this link to see the various support options that are available to better meet your needs:  http://support.microsoft.com/default.aspx?id=fh;en-us;offerprophone.

    Trevor Hancock (Microsoft)
    Please remember to "Mark As Answer" the replies that help.

    Friday, September 28, 2012 7:03 PM
  • Try thjis code project.  I t has a form which you should be able to enter the manual options and verify that the algorithm and parameters are correct.  the alogorithm will create an error like what you are seeing if you don't get the paramters correct.  It is based on the Sha alogithm which I'm a little bit familar and helped debug some code a number of years ago to impliment the alogorithm on a microcontroller.

    http://www.codeproject.com/Articles/18610/Elliptic-Curve-Diffie-Hellman-Cryptography


    jdweng

    Friday, September 28, 2012 7:54 PM
  • Are you still getting this error on the newest framework versions?  The IsEphemeral property has been hardened against devices not returning standardized answers, so this exception should be mitigated now.
    Sunday, March 13, 2016 4:51 PM