ExportParameters returns Invalid type specified error
Hi all,
Some time ago a customer of mine was trying to export the private key associated to a certificate stored in a smart card, and for that he was trying to use the RSACryptoServiceProvider.ExportParameters method with a code like the following:
"
System.Security.Cryptography.X509Certificates.X509Certificate2 cert = GetCert(certName);
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey;
RSAParameters params = rsa.ExportParameters(true);
"
But ExportParameters was returning the following exception:
"
System.Security.Cryptography.CryptographicException: Invalid type specified
"
To troubleshoot this error, we took traces with the following debugger script of mine: CryptoAPI Tracer script.
With those traces we saw that the error came from CryptExportKey API. The reason of the error was that the third-party Cryptographic Service Provider (CSP) associated to the certificate won’t allow us to export the private keys from the smart card. This actually makes sense if we think about the main purpose of smart cards in this scenario: hold private keys which can only be accessed directly from the smart card whenever they are needed to sign or decrypt data.
For completeness, this is the relevant sequence of calls written by the script:
"
>>>>>>>>>>>>>>>>>>>>>>
CryptAcquireContextW (0xc58)
IN
pszContainer
002817c0 "Some Container"
pszProvider
0612e828 "My third-party smart card Prov"
0612e868 "ider"
dwProvType
PROV_RSA_FULL
dwFlags
0
OUT
hProv
0x6bd87d8
RESULT
CryptAcquireContextW (0xc58) SUCCEEDED
<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>
CryptGetUserKey (0xc58)
IN
hProv
0x6bd87d8
dwKeySpec
AT_SIGNATURE
OUT
hUserKey
0x6b0d800
RESULT
CryptGetUserKey (0xc58) SUCCEEDED
<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>
CryptExportKey (0xc58)
IN
hKey
0x6b0d800
hExpKey
0
dwBlobType
PRIVATEKEYBLOB
dwFlags
0
pbData
NULL
dwDataLen
4
OUT
dwDataLen
4
RESULT
CryptExportKey (0xc58) FAILED
LastErrorValue: (HRESULT) 0x8009000a (2148073482) - Invalid type specified.
LastStatusValue: (NTSTATUS) 0 - STATUS_WAIT_0
<<<<<<<<<<<<<<<<<<<<<<
"
I hope this helps.
Regards,
Alex (Alejandro Campos Magencio)