2015-12-17 30 views
3

我已經使用System.Security.Cryptography.X509Certificates.X509Store一段時間來枚舉機器上的所有TLS證書(在代碼中驗證是否重定向到SSL將工作並警告證書是否丟失)。我有以下的上市功能,這有助於我診斷,就想現在的一個問題,但我似乎無法找到我需要的數據:C#枚舉TLS證書支持的所有主機名

 System.Security.Cryptography.X509Certificates.X509Store store = new System.Security.Cryptography.X509Certificates.X509Store(System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine); 

     store.Open(System.Security.Cryptography.X509Certificates.OpenFlags.ReadOnly); 

     DateTime utcNow = DateTime.UtcNow; 
     foreach (System.Security.Cryptography.X509Certificates.X509Certificate2 mCert in store.Certificates) 
     { 
      writer.WriteStartElement("certificate"); 
      writer.WriteAttributeString("friendlyName", mCert.FriendlyName); 
      writer.WriteAttributeString("subjectName", mCert.SubjectName.Name); 
      writer.WriteAttributeString("subject", mCert.Subject); 
      writer.WriteAttributeString("simpleName", mCert.GetNameInfo(System.Security.Cryptography.X509Certificates.X509NameType.SimpleName, false)); 
      writer.WriteAttributeString("dnsName", mCert.GetNameInfo(System.Security.Cryptography.X509Certificates.X509NameType.DnsName, false)); 
      writer.WriteAttributeString("certhash", mCert.GetCertHashString()); 
      writer.WriteAttributeString("effectivedate", mCert.GetEffectiveDateString()); 
      writer.WriteAttributeString("expirationdate", mCert.GetExpirationDateString()); 
      writer.WriteAttributeString("format", mCert.GetFormat()); 
      writer.WriteAttributeString("keyalgorithm", mCert.GetKeyAlgorithm()); 
      writer.WriteAttributeString("publickey", mCert.GetPublicKeyString()); 
      writer.WriteAttributeString("serialnumber", mCert.SerialNumber); 
      writer.WriteAttributeString("hasprivatekey", XmlConvert.ToString(mCert.HasPrivateKey)); 
      writer.WriteAttributeString("issuer", mCert.Issuer); 
      // NOTE: X509Certificate2 as provided by .NET uses local datetimes, so we need to convert them to the sane choice of UTC here 
      writer.WriteAttributeString("notafterutc", XmlConvert.ToString(mCert.NotAfter.ToUniversalTime(), XmlDateTimeSerializationMode.Utc)); 
      writer.WriteAttributeString("notbeforeutc", XmlConvert.ToString(mCert.NotBefore.ToUniversalTime(), XmlDateTimeSerializationMode.Utc)); 
      writer.WriteAttributeString("validnow", XmlConvert.ToString(mCert.NotBefore.ToUniversalTime() < utcNow && utcNow < mCert.NotAfter.ToUniversalTime())); 
      writer.WriteAttributeString("timeuntilexpiration", XmlConvert.ToString(mCert.NotAfter.ToUniversalTime() - utcNow)); 
      writer.WriteAttributeString("thumbprint", mCert.Thumbprint); 
      writer.WriteAttributeString("version", mCert.Version.ToString()); 
      writer.WriteEndElement(); // certificate 
     } 
     writer.WriteEndElement(); // certificates 
     writer.WriteEndResponse(); 

由於支持新的替代的願望主機名在同一個IP地址上,我們最近切換到使用具有多個主機的UCC證書。不幸的是,上面的代碼似乎無法看到證書「主題備用名稱」字段中指定的任何備用主機名(一個UCC證書用於指定多個主機),並且我無法查找財產或功能,讓我訪問這些數據。

總之,有沒有人知道如何從使用C#的本地安裝證書的「使用者替代名稱」字段獲取支持的主機名稱列表?

回答

2

不是作爲一個單獨的列表,但作爲一個單獨的列表 - 只要找到主題備用名稱擴展並調用.Format(bool multiLine)方法:

var sanNames = String.Empty; 
foreach (var ext in mCert.Extensions) { 
    if (ext.Oid.Value == "2.5.29.17") { 
     sanNames = ext.Format(false); 
    } 
} 
if (!String.IsNullOrEmpty(sanNames)) {// write sanNames variable to XML} 

編輯由詹姆斯:以下是完整的修改:

  System.Security.Cryptography.X509Certificates.X509Extension uccSan = mCert.Extensions["2.5.29.17"]; 
      if (uccSan != null) 
      { 
       foreach (string nvp in uccSan.Format(true).Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)) 
       { 
        writer.WriteStartElement("alternateName"); 
        string[] parts = nvp.Split('='); 
        string name = parts[0]; 
        string value = (parts.Length > 0) ? parts[1] : null; 
        writer.WriteAttributeString("type", name); 
        writer.WriteAttributeString("value", value); 
        writer.WriteEndElement(); // alternateName 
       } 
      } 
+0

你真的是加密人!謝謝一堆! – James