首页 > 解决方案 > X509 证书预期用途和 SSL

问题描述

我正在考虑允许用户为我们的一项服务选择将用于 SSL 的证书,用户需要选择商店名称的初始值,并且证书列表将显示在下拉列表中,我在阅读后将其删除这篇文章认为证书应该只来自本地计算机下的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);
                    }
                }
            }

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

证书详情,

检查属性窗口,我得到以下内容, 在此处输入图像描述上面的代码似乎没有检测到这个证书,在 IIS 下检查,我可以将这个特定的证书用于 Https,我的代码是否缺少一些东西检测有效的 SSL 证书?

标签: c#iisx509certificate2

解决方案


MMC UI 有一点误导。它的意思是“启用证书已经声明的所有目的”。

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

IETF RFC 3280 第 4.2.1.13 节

如果存在扩展,则证书必须仅用于指定的目的之一。如果指示了多个目的,则应用程序不需要识别所有指示的目的,只要存在预期目的即可。使用应用程序的证书可能要求指明特定用途,以便该证书可以被该应用程序接受。

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

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

相应的证书必须仅包含 [RFC2459] 第 4.2.1.13 节中定义的扩展密钥使用字段扩展的一个实例,其 KeyPurposeID 具有值:

id-kp-timeStamping。这个扩展必须是关键的。

但是,TLS 从来没有真正谈论过它。

所以你需要更复杂。Web 浏览器使用的逻辑是if (!hasEkuExtension || hasServerAuthEku), 与您的if (hasServerAuthEku).

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


推荐阅读