使用GetRSAPrivateKey和.net内核以编程方式设置智能卡PIN



多年来,我一直在使用此链接中的扩展方法来访问智能卡上的证书并以编程方式提供PIN,而无需向用户打开请求PIN掩码。现在有了新版本的.net内核,它就不再工作了,所以我正在努力修复它。

我知道现在有了新版本的框架,最好使用

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] == '')
{
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设置代码复制自https://stackoverflow.com/a/42630670/6535399;因为这个问题似乎有更好的发现,这里的答案更一般。

最新更新