在 c# 中列出 SSL 证书(重新创建 IIS 绑定对话框)

List SSL certificates in c# (recreate IIS bindings dialog)

我正在尝试列出 IIS 绑定对话框中列出的 SSL 证书 - 但我无法这样做。我在周围跳舞,谁能告诉我它们存放在哪里? (我在下面截取的代码不是 1:1 匹配 - 我不知道它们在哪家商店)。

X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
foreach (var x in store.Certificates)
{
     radDropDownListIISCert.Items.Add(new RadListDataItem(x.FriendlyName, x.SerialNumber));
}

他们在 StoreLocation.LocalMachine。此外,X509Store 实现了 IDisposible,因此它应该包含在 using 语句中。

using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
{
     store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
     foreach (var x in store.Certificates)
     {
          radDropDownListIISCert.Items.Add(new RadListDataItem(x.FriendlyName, x.SerialNumber));
     }
}

这有点棘手:

首先 X509Certificate 已过时,请改用 X509Certificate2。 第二个商店是 IDisposable 所以确保调用 .Close() 或使用“using”语句。

我的解决方案:

var store = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser);
        try
        {
            var targetCollection = new List<X509Certificate2>();
            
            store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
            var certificates = store.Certificates.Cast<X509Certificate2>();
            targetCollection.AddRange(certificates);
        }
        catch(Exception e)
        {
            //Handle that
        }
        finally
        {
            store.Close();
        }

当然 select 从 tempCollection 中的证书到您的证书的适当字段:

targetCollection.Select(c => new RadListDataItem(c.FriendlyName, c.SerialNumber));

所有答案 return 证书比 IIS 绑定对话框多。 我比较了显示和未显示的证书之间的差异。 区别似乎是 EnhancedKeyUsageList:{Server Authentication (1.3.6.1.5.5.7.3.1)} - 对于显示的和 EnhancedKeyUsageList : {Client Authentication (1.3.6.1.5.5.7.3.2)} - 对于那些不是。 所以基本上 IIS 绑定对话框只显示相关证书(那些打算用作服务器身份验证的证书)。

在代码世界中获取这些信息有点棘手,我是这样做的:

        List<X509Certificate2> certificates = new List<X509Certificate2>();

        X509Store store1 = new X509Store(StoreName.My, StoreLocation.LocalMachine);
        try
        {
            store1.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

            foreach (var certificate in store1.Certificates)
            {
                foreach (var extension in certificate.Extensions)
                {
                    if (extension.Oid.FriendlyName == "Enhanced Key Usage" && extension is X509EnhancedKeyUsageExtension enhancedKeyUsageExtension)
                    {
                        foreach (var item in enhancedKeyUsageExtension.EnhancedKeyUsages)
                        {
                            if (item.FriendlyName == "Server Authentication")
                            {
                                certificates.Add(certificate);
                            }
                        }
                    }
                }
            }
        }
        finally
        {
            store1.Close();
        }