c# - X509 证书预期用途和 SSL

标签 c# iis x509certificate2

我正在考虑允许用户选择一个证书,该证书将用于我们的一项服务的 SSL,最初用户需要选择一个商店名称,证书列表将显示在下拉列表中,我删除了读完这篇article证书只能来自 本地计算机 下的 MY 存储位置。在查看了几篇文章后,我创建了以下代码

using (var store = new X509Store(StoreName.My,StoreLocation.LocalMachine))
        {
            store.Open(OpenFlags.ReadOnly);

            var certificates = store.Certificates;
            foreach (var c in certificates)
            {
                bool isSslCompatible = false;
                bool ekuExists = false;//when this value does not exist, certificate can be used for all purposes [ https://tools.ietf.org/html/rfc3280#section-4.2.1.13 ] 
                if (c.HasPrivateKey)//only chose those that have a private key
                {

                    foreach (X509Extension extension in c.Extensions)
                    {
                        if (extension.Oid.Value == "2.5.29.37")//[ Friedlname = Enhanced Key Usage, names are localised, firendly name cannot be used
                        {
                            ekuExists = true;
                            X509EnhancedKeyUsageExtension ext = (X509EnhancedKeyUsageExtension) extension;
                            OidCollection oids = ext.EnhancedKeyUsages;
                            foreach (Oid oid in oids)
                            {
                                if (/*oid.FriendlyName == "Server Authentication" || -- cannot be used as friendly names are localised*/
                                    oid.Value == "1.3.6.1.5.5.7.3.1")
                                {
                                    isSslCompatible = true;
                                }
                            }
                        }
                    }
                    if (isSslCompatible || !ekuExists)//add only if value is ssl compatible
                    {
                        SSLCertficate certificate = new SSLCertficate();

                        certificate.CertificateHash = c.GetCertHash();
                        certificate.CertificateHashString = c.GetCertHashString();
                        certificate.CertificateThumbPrint = c.Thumbprint;
                        certificate.FriendlyName = c.FriendlyName;
                        certificate.SubjectName = c.Subject;
                        certificate.HasPrivateKey = c.HasPrivateKey;

                        sslCertificates.Add(certificate);
                    }
                }
            }

上面代码的这个问题是它看不到证书并且没有所有预期目的,我不确定如何获得这些,

Certificate Details ,

检查属性窗口,我得到以下信息, enter image description here ,上面的代码似乎没有检测到这个证书,在 IIS 下检查,我能够将这个特定的证书用于 Https,我的代码是否缺少一些东西来检测有效的 SSL 证书?

最佳答案

MMC 用户界面有点误导。它的意思是“启用证书已经声明的所有用途”。

在您的过滤代码中,您要求存在 EKU 扩展并具有 TLS 服务器身份验证目的。

IETF RFC 3280 section 4.2.1.13

If the extension is present, then the certificate MUST only be used for one of the purposes indicated. If multiple purposes are indicated the application need not recognize all purposes indicated, as long as the intended purpose is present. Certificate using applications MAY require that a particular purpose be indicated in order for the certificate to be acceptable to that application.

这通常被认为是“如果没有扩展,则证书被认为对所有目的都有效”。 TLS RFC 似乎没有具体引用 id-kp-serverAuth EKU,这意味着它是一个“严格约定”的应用程序约定来检查它。

有不同的规范可以覆盖“对所有目的有效”的隐式评估,例如 IETF RFC 3161 (可信时间戳)第 2.3 节:

The corresponding certificate MUST contain only one instance of the extended key usage field extension as defined in [RFC2459] Section 4.2.1.13 with KeyPurposeID having value:

id-kp-时间戳。此扩展必须是关键的。

但是,再说一次,TLS 从未真正谈论过它。

所以你需要更复杂一些。 Web 浏览器使用的逻辑是 if (!hasEkuExtension || hasServerAuthEku),对比你的 if (hasServerAuthEku)

此外,您应该(几乎)总是通过它们的Value 来比较Oid 对象,而不是它们的FriendlyNameFriendlyName 已本地化,因此您的代码只能在英语系统上可靠地运行。 Oid.Value 值是证书中的实际内容(文本化形式)。 (唯一的异常(exception)是当 Value 为 null 时,因为这意味着 API 试图表示一个没有定义 OID 的值(由于 Curve25519,这实际上只发生在 ECCurve 上))。

关于c# - X509 证书预期用途和 SSL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51322480/

相关文章:

android - 使用 Xamarin Android 与客户端证书进行 SSL 通信

c# - Xamarin for VS 2015 - 灾难性失败

iis - 如何进行 IIS 站点/内容备份?

wcf - 忽略一次点击登录页面的客户端证书弹出窗口 - 但仍需要证书才能获得服务

internet-explorer - 如何停止 IIS 要求对本地主机上的默认网站进行身份验证

c# - 如何在 C# 中使用私钥? "Cannot find the requested object."

c# - X509Certificate2 访问私钥到安全 token

c# - 无法将类型 IEnumerable 转换为列表

c# - 我可以将此 C# 代码转换为一些 Linq 代码吗?

c# - 如何在同一解决方案中从 VB.NET 项目访问 C# 内部属性?