多年以来,我一直使用此link处的扩展方法来访问智能卡上的证书并以编程方式提供PIN,而无需向用户打开请求PIN掩码。现在,随着新版本的.net core不再起作用,因此我正在尝试对其进行修复。
我知道现在有了新版本的框架,最好使用
RSA rsa = certificate.GetRSAPrivateKey();
但是以这种方式,我无法访问调用提供PIN的本机方法所需的CspKeyContainerInfo(KeyContainerName,ProviderName,ProviderType)
是否可以使用RSA对象访问相同的信息?
或者是否有更好/更新的方法通过程序提供智能卡的PIN?
您拥有的代码仅在Windows CAPI提供了私钥时才有效。如果私钥是Windows CNG提供的,则需要使用它的CNG形式。
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}");
}
从https://stackoverflow.com/a/42630670/6535399复制的RSACng PIN设置代码;因为这个问题似乎具有更好的发现,而且答案在这里更为笼统。