I am using a Gemalto Smart card
to sign XML
documents.
I have a method which returns the certificate
and searches by the thumbprint
that is hard coded.
I am unable to obtain the private key
from that Smart card
and sign the doc with it.
It returns null
when I debug
the app.
My goal is to get the private key
and then ask the user for the PIN
to authorize the signing of the document.
public static X509Certificate2 GetDefaultCertificateStoredOnTheCard()
{
X509Store store = new X509Store("MY", StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindByTimeValid, DateTime.Now, true);
// by thumbprint, there is only one
certs = certs.Find(X509FindType.FindByThumbprint, "6BB4F9D483206F44A992799541114536579CF2B3", true);
if (certs.Count == 0)
{
throw new ArgumentException("Please insert smart card to obtain certificate.");
}
X509Certificate2 cert = certs[0];
RSACryptoServiceProvider key;
if (cert.HasPrivateKey)
{
// software cert
key = cert.PrivateKey as RSACryptoServiceProvider;
}
else
{
// certificate from smartcard
CspParameters csp = new CspParameters(1, "Microsoft Base Smart Card Crypto Provider");
csp.Flags = CspProviderFlags.UseDefaultKeyContainer;
key = new RSACryptoServiceProvider(csp);
}
return cert;
}
As you can see if the key is null, set the key
to use the Microsoft Base Smart Card Crypto Provider
.
I have noticed on device manager that my Smart Card Reader
is Microsoft Usbccid Smartcard Reader
.
Not sure if I should set something else here , it brings this window and an error with it.
The very purpose of a smart card is to protect confidential data. There are no more confidential data than the private key (often this never leaves the smart card), so it is a sign of correct functioning, that you don't get it.
Actually you have to let the smart card do the signature, probably by sending the hash value of your XML document.