假设我从 Windows 的 keystore 中选择了一个证书,并且在签名时,我需要确定插入读卡器中的智能卡是否正确...
下面是一些示例代码:
// finding the certificate
X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
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, "123456BLAHBLAHAE3C", true);
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);
}
现在,当我想要签署数据时,我如何才能知道当前插入的智能卡是否真的是我正在寻找的智能卡(与 Windows keystore 中的智能卡相匹配)?
我问这个问题,因为现在当我签署数据时,我会收到输入智能卡 PIN 的提示,但我插入的卡甚至不是我选择的凭据......而且无论如何它只是签署了数据......
最佳答案
经过一整天的故障排除和互联网挖掘。事实证明,我根本不需要这样做。事实上,这是我犯的一个错误。
当您从商店选择证书时,X509Certificate
你得到的对象实际上拥有它需要的一切,比如 HasPrivateKey
和 PrivateKey
(一个 RSACryptoServiceProvider 对象,不是实际的私钥),Windows 知道从哪里获得 PrivateKey
使用这些信息...包括验证读卡器中的智能卡是否有正确的智能卡。
我的问题是在某些时候我使用了 cert.GetRawCertData()
获取原始字节来执行我自己的证书验证,最后我重新创建了一个 X509Certificate
原始字节中的对象...我认为它会给我原来的 X509Certificate
对象,但是哦,我错了。两者 HasPrivateKey
和 PrivateKey
都走了。
现在,我不确定这是否是 Windows 10 中的新功能。但是正如您在下面看到的,我实际上根本不需要检查读卡器中的内容...
为了解决这个问题,我仔细检查读卡器中的智能卡的初衷是确保签名操作确实是使用正确的智能卡完成的(我在 Java 中遇到了问题,您可以插入不同的卡并输入PIN 码错误的卡,它仍会为您签名)。但是,更好的方法实际上是使用 PublicKey
并验证数据。
// so after you finished signing the data...
// make a new RSACryptoServiceProvider and verify it like this:
RSACryptoServiceProvider rsa = cert.PublicKey.Key as RSACryptoServiceProvider;
Debug.WriteLine(" Verify data >> " + (rsa.VerifyData(data, alg, signature) ? "OK" : "FAILED"));
Debug.WriteLine("Verify signature >> " + (rsa.VerifyHash(hash, alg, signature) ? "OK" : "FAILED"));
注意:不要使用 using
用于验证 RSACryptoServiceProvider
,如果这样做,您将关闭 PublicKey.Key
上的静态句柄,如果您尝试再次验证(无论出于何种原因),您将获得 Safe Handle has been closed
异常。
关于c# - 如何检查智能卡读卡器中的匹配证书?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46899187/