从浏览器证书存储中获取有效证书以进行签名

本文关键字:证书 获取 浏览器 存储 有效 | 更新日期: 2023-09-27 18:35:44

我需要在 WPF 中创建一个简单的签名客户端。工作站已使用智能卡导入的一组证书进行配置。其中之一是签名证书,其他用于电子邮件身份验证和加密。

所以我正在制作一个简单的下拉列表,用户可以从列表中选择他的首选证书,但我想排除与文档签名无关的证书。通过检查证书,我可以读取其用途,然后我想以编程方式读取它。

到目前为止,我写道:

        IEnumerable<Certificate> certificates;
        X509Store store = new X509Store(StoreLocation.CurrentUser);
        store.Open(OpenFlags.ReadOnly);
        try
        {
            certificates = from X509Certificate2 certificate in store.Certificates
                           where certificate.HasPrivateKey
                           && certificate.NotAfter <= DateTime.Now && certificate.NotBefore >= DateTime.Now
                           select new Certificate
                           {
                               CommonName = certificate.SubjectName.Decode(X500DistinguishedNameFlags.UseUTF8Encoding),
                               Id = Convert.ToString(certificate.GetSerialNumber())
                           };
        }
        finally
        {
            store.Close();
        }

上述代码的结果是一个列表,其中至少包含一个众所周知的电子邮件身份验证证书。

为了检查证书是否usage attribute == non repudiation,要添加什么条件?

从浏览器证书存储中获取有效证书以进行签名

OP接受的答案的关键部分是:

您可以查看Extensions集合并搜索KeyUsage扩展。

https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509keyusageextension(v=vs.110).aspx

有一个KeyUsages属性,它应该告诉您实际检查的证书类型。

向@WiktorZychla致敬

        IEnumerable<Certificate> certificates;
        X509Store store = new X509Store(StoreLocation.CurrentUser);
        store.Open(OpenFlags.ReadOnly);
        try
        {
            certificates = from X509Certificate2 certificate in store.Certificates
                           where certificate.HasPrivateKey
                               //&& certificate.NotAfter <= DateTime.Now && certificate.NotBefore >= DateTime.Now
                           //Commented because doesn't work, strangely
                           && certificate.Extensions.OfType<X509KeyUsageExtension>().Any(ku => ku.KeyUsages == X509KeyUsageFlags.NonRepudiation)
                           select new Certificate
                           {
                               CommonName = certificate.SubjectName.Decode(X500DistinguishedNameFlags.UseUTF8Encoding),
                               Id = Encoding.UTF8.GetString(certificate.GetSerialNumber())
                           };
        }
        finally
        {
            store.Close();
        }