C# 中来自智能卡的证书

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/566179/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 08:25:42  来源:igfitidea点击:

Certificates from SmartCard in C#

c#certificatesmartcard

提问by

How can I ensure to I am accesing the Certificates from my SmartCard and not form my personal certificate store in c#? and How can I make my RSACryptoProvider to utilize my smart card certificate private key?

如何确保我从我的智能卡访问证书而不是在 c# 中形成我的个人证书存储?以及如何让我的 RSACryptoProvider 使用我的智能卡证书私钥?

thanks

谢谢

Wally

沃利

采纳答案by ?eljko Tanovi?

Sometimes, especially if you are not using default key container name on the smart card (recommended by Microsoft), certificates are not copied to local certificate store. The solution is to use crypto api to access the key with KP_CERTIFICATE, construct certificate from the retrieved data, and assign it a new RSACryptoServiceProvider constructed using your own key container name.

有时,特别是如果您没有在智能卡上使用默认密钥容器名称(Microsoft 推荐),证书不会复制到本地证书存储区。解决方案是使用crypto api通过KP_CERTIFICATE访问密钥,根据检索到的数据构造证书,并为其分配一个使用您自己的密钥容器名称构造的新RSACryptoServiceProvider。

The pseudo C# code follows:

伪 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);
}

回答by Craig Delthony

You will need to go through your Cryptographic Service Provider (CSP) for your smartcard. On Windows (2000, XP, and Vista) any time you insert your smartcard into a smartcard reader all the certificates on it are propogated to your personal certificate store. Your private key stays on your smart card. What that means is if you use your certificate (for example to digitally sign an e-mail) then you are prompted to insert your smart card. If your smart card requires a PIN you will be asked to input it. The reason for this is that there is one location for applications to look for user certificates, your personal certificate store, so applications don't have to be rewritten just to handle certificates on smartcards.

您需要通过加密服务提供商 (CSP) 获取智能卡。在 Windows(2000、XP 和 Vista)上,每当您将智能卡插入智能卡读卡器时,其上的所有证书都会传播到您的个人证书存储区。您的私钥保留在您的智能卡上。这意味着如果您使用您的证书(例如对电子邮件进行数字签名),则会提示您插入智能卡。如果您的智能卡需要 PIN 码,您将被要求输入它。这样做的原因是应用程序可以在一个位置查找用户证书,即您的个人证书存储,因此不必为了处理智能卡上的证书而重写应用程序。