首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何以编程方式设置X509Certificate2的个人识别码?

如何以编程方式设置X509Certificate2的个人识别码?
EN

Stack Overflow用户
提问于 2017-03-06 21:20:25
回答 2查看 2.1K关注 0票数 2

我每天都需要向send服务发送数据,所以我制定了一个计划任务来运行我的代码。问题是with服务需要一个带有PIN码的证书。我已经附上了证书,但我找不到一种方法来设置它的个人识别码,因此它显示弹出每次手动输入它。

下面是我的证书代码:

代码语言:javascript
复制
private void SendData(string data)
    {
        using (SerWSService webService = new SerWSService())
        {
            string certificateSN = "serial number for the certificate";
            webService.ClientCertificates.Add(FindCertificate(certificateSN));

            webService.SendData(data);
        }
    }

private X509Certificate2 FindCertificate(string certserial)
    {
        X509Certificate2 WPE_UserCert = null;
        X509Store wstore = default(X509Store);
        wstore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        wstore.Open(OpenFlags.ReadOnly);
        var wcerts = wstore.Certificates;
        foreach (var wcert in wcerts)
        {
            if (wcert.SerialNumber.ToUpper() == certserial.Replace(" ", "").ToUpper())
            {
                WPE_UserCert = wcert;
                break;
            }
        }
        wstore.Close();

        if (WPE_UserCert != null)
        {
            //TO DO: add PIN code to certificate

        }

        return WPE_UserCert;
    }

有什么方法可以将PIN设置为证书吗?

EN

回答 2

Stack Overflow用户

发布于 2017-03-07 00:27:45

不,因为证书没有PIN;(私有)密钥有。

如果你正在寻找一个具有私钥的证书,并且你将该证书传递给一个需要统一密钥对的类(例如SslStream,HttpClient),那么就没有真正/好的解决方案了。

如果您自己使用私钥,则有一些回旋余地:

代码语言:javascript
复制
using (RSA rsa = cert.GetRSAPrivateKey())
{
    RSACng rsaCng = rsa as RSACng;
    RSACryptoServiceProvider rsaCsp = rsa as RSACryptoServiceProvider;

    if (rsaCng != null)
    {
        // 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);
    }
    else if (rsaCsp != null)
    {
        // This is possible, but painful.
        // Copy out the CspKeyContainerInfo data into a new CspParameters,
        // build the KeyPassword value on CspParameters,
        // Dispose() the existing instance,
        // and open a new one to replace it.
        //
        // But if you really called GetRSAPrivateKey() and it has returned an RSACng for
        // your device once, it pretty much will forever (until the next
        // new RSA type for Windows is invented... at which point it still
        // won't return an RSACryptoServiceProvider).
    }
    else
    {
        // No other built-in RSA types support setting a PIN programmatically.
    }

    // Use the key here.
    // If you needed to return it, don't put it in a using :)
}
票数 4
EN

Stack Overflow用户

发布于 2021-05-18 17:26:31

对于CSP私钥,使用CryptAcquireCertificatePrivateKey获取PIN句柄,然后使用CryptSetProvParam(h,PP_SIGNATURE_PIN,pin,0)设置CryptoProv。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42626742

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档