X509证书预期用途和SSL

时间:2018-07-13 09:54:31

标签: 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证书的代码方面我还缺少什么?

1 个答案:

答案 0 :(得分:2)

MMC UI有点误导。意思是“启用证书已经要求的所有目的”。

在您的过滤代码中,您需要提供一个EKU扩展名并具有TLS服务器身份验证目的。

IETF RFC 3280 section 4.2.1.13

  

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

这通常是指“如果没有扩展名,则该证书被视为对所有目的均有效”。 TLS RFC似乎没有专门引用id-kp-serverAuth EKU,这意味着要检查它是“通过严格的约定”应用程序约定。

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

  

     相应的证书必须仅包含      [RFC2459]节中定义的扩展密钥用法字段扩展      4.2.1.13,KeyPurposeID的值为:

     

id-kp-timeStamping。此扩展名必须是至关重要的。

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

因此您需要更加复杂。 Web浏览器使用的逻辑是if (!hasEkuExtension || hasServerAuthEku),而不是您的if (hasServerAuthEku)

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