C# C语言中的智能卡证书
如何确保我正在从智能卡访问证书,而不是在c中形成个人证书存储? 我如何让我的加密提供商使用我的智能卡证书私钥 谢谢C# C语言中的智能卡证书,c#,certificate,smartcard,C#,Certificate,Smartcard,如何确保我正在从智能卡访问证书,而不是在c中形成个人证书存储? 我如何让我的加密提供商使用我的智能卡证书私钥 谢谢 Wally您需要通过加密服务提供商CSP获取智能卡。在Windows 2000、XP和Vista上,每当您将智能卡插入智能卡读卡器时,智能卡上的所有证书都会分发到您的个人证书存储中。您的私钥保留在智能卡上。这意味着,如果您使用证书(例如)对电子邮件进行数字签名,则系统会提示您插入智能卡。如果您的智能卡需要PIN码,系统将要求您输入PIN码。原因是应用程序只有一个位置可以查找用户证书
Wally您需要通过加密服务提供商CSP获取智能卡。在Windows 2000、XP和Vista上,每当您将智能卡插入智能卡读卡器时,智能卡上的所有证书都会分发到您的个人证书存储中。您的私钥保留在智能卡上。这意味着,如果您使用证书(例如)对电子邮件进行数字签名,则系统会提示您插入智能卡。如果您的智能卡需要PIN码,系统将要求您输入PIN码。原因是应用程序只有一个位置可以查找用户证书,即您的个人证书存储,因此应用程序不必仅为处理智能卡上的证书而重写。有时,特别是如果您没有在Microsoft推荐的智能卡上使用默认密钥容器名称,证书不会复制到本地证书存储。解决方案是使用crypto api访问具有KP_证书的密钥,从检索到的数据构造证书,并为其分配一个使用您自己的密钥容器名称构造的新RSACryptoServiceProvider 伪C代码如下所示:
int reti = CryptoApi.CryptGetUserKey(_hprovider, keytype, ref userKey);
if (reti)
{
reti =CryptoApi.CryptGetKeyParam(_userKey, KP_CERTIFICATE, ref pbdata, ref pwddatalen, 0);
}
if (reti || pwddatalen>0)
{
byte[] data = new byte[pwddatalen];
ret = CryptoApi.CryptGetKeyParam(_userKey, KP_CERTIFICATE, data, ref pwddatalen, 0);
if (ret)
{
X509Certificate2 c = new X509Certificate2(data);
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindByThumbprint, c.Thumbprint, validonly);
store.Close();
if (col.Count != 1)
{
//not found in store - CSP didn't copy it
c.PrivateKey = PrivateKey(keytype);
return c;
}
else
{
return col[0];
}
}
}
private RSACryptoServiceProvider PrivateKey (KeyType keytype)
{
CspParameters csparms = new CspParameters();
csparms.KeyContainerName = _containerName;
csparms.ProviderName = _provider;
csparms.ProviderType = 1;
csparms.Flags = CspProviderFlags.UseMachineKeyStore | CspProviderFlags.UseExistingKey;
csparms.KeyNumber = (int)keytype;
return new RSACryptoServiceProvider(csparms);
}
我有点困惑,什么时候需要这样的代码?如果说您知道智能卡主题行,则在注册时为每个用户存储该主题行,然后将证书存储在DB中,然后每次有人尝试登录时,将DB中的证书与Request.ClientCertificate中给出的证书进行比较,对吗?您只能将证书的公共部分存储在某个地方,而比较证书的公共部分并不足以证明您拥有私钥。因此,您需要私钥访问来签署一些数据并证明这一点。加密提供程序有时会自动向证书存储区提供私钥,有时则不会。如果没有,这是得到它的方法。有没有一篇文章是你发现这种类型的代码的?您的代码有点不完整,包含未声明的变量。其中有一篇C文章描述了检查私钥有效性的过程。我一直认为,使用X509Certificate对有效证书进行简单检查,以检查散列是否是客户端证书中的有效散列就足够了,但我认为可以用自签名证书伪造散列。任何信息都会有帮助。我仍然不明白为什么我需要检查私钥。C的API不应返回与注册时使用的原始证书相同的ClientCertificate,如果事实上ClientCertificate变量是伪造的,则解密应导致上下文中出现无效证书。ClientCertificate.Hi,您可能需要了解一些关于公钥-私钥加密的知识。。。将公钥的散列和其他散列进行比较不足以证明其身份,因为公钥是公共的,很抱歉,这里不能将其设为粗体,所以任何人都可以进行拦截。为了证明身份,您需要使用私钥对数据段进行签名,并使用私钥对哈希进行有效加密。可以使用公钥验证此签名,并使用它解密散列并将其与数据进行比较。这就是您需要访问私钥的原因。或者我误解了你的问题?Java应用程序可以使用智能卡/证书,而无需在个人存储上安装证书。如果之前未安装,.NET应用程序找不到必要的证书。