I have been using an extension method found at this link for years, to access the certificate on a smart card and supply the PIN programmatically without opening the request PIN mask to the user. Now with new versions of .net core it no longer works, so I'm trying to fix it.
I know that now with new versions of the framework it is better to use
RSA rsa = certificate.GetRSAPrivateKey();
however in this way I have no access to the CspKeyContainerInfo (KeyContainerName, ProviderName, ProviderType) required to call the native methods that provide PIN
Is there any way to access the same information using the RSA object?
Or is there a better / newer method to provide the PIN of the smart card by program?
The code that you have works only when the private key is provided by Windows CAPI. If the private key is provided by Windows CNG you need to do the CNG form of it.
private static RSA GetRSAPrivateKeyWithPin(this X509Certificate2 cert, string pin)
{
RSA rsa = cert.GetRSAPrivateKey();
if (rsa is RSACryptoServiceProvider rsaCsp)
{
// Current code
SetPin(rsaCsp);
return rsa;
}
if (rsa is RSACng rsaCng)
{
// Set the PIN, an explicit null terminator is required to this Unicode/UCS-2 string.
byte[] propertyBytes;
if (pin[pin.Length - 1] == '\0')
{
propertyBytes = Encoding.Unicode.GetBytes(pin);
}
else
{
propertyBytes = new byte[Encoding.Unicode.GetByteCount(pin) + 2];
Encoding.Unicode.GetBytes(pin, 0, pin.Length, propertyBytes, 0);
}
const string NCRYPT_PIN_PROPERTY = "SmartCardPin";
CngProperty pinProperty = new CngProperty(
NCRYPT_PIN_PROPERTY,
propertyBytes,
CngPropertyOptions.None);
rsaCng.Key.SetProperty(pinProperty);
return rsa;
}
// If you're on macOS or Linux neither of the above will hit. There's
// also no standard model for setting a PIN on either of those OS families.
rsa.Dispose();
throw new NotSupportedException($"Don't know how to set the PIN for {rsa.GetType().FullName}");
}
RSACng PIN-set code copied from https://stackoverflow.com/a/42630670/6535399; because this question seems like it has better discovery, and the answer is more general here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With