2015-12-31 12 views
5

ho trovato su internet unico modo per ottenuto tutti i certificati dalle iis e lo faccio nel modo seguente (C#):Come ottenere il certificato dal legame specifico C#

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

Ora cerco di ottenere un certificato specifico di associazione specifica, come posso farlo in C#?

risposta

6

I certificati si tengono assolutamente alcuna informazione circa le associazioni utilizzati in IIS, quindi non è possibile recuperare i certificati dalla macchina e si aspettano loro di avere tutto ciò che riguarda IIS. Avresti bisogno di interrogare tali informazioni da IIS.

Per fare ciò, è necessario aggiungere un riferimento alla libreria che è possibile trovare in %windir%\system32\inetsrv\Microsoft.Web.Administration.dll (nota: IIS 7 o versione successiva deve essere installata). Dopo questo, si può fare qualcosa di simile al seguente:

ServerManager manager = new ServerManager(); 
Site yourSite = manager.Sites["yourSiteName"]; 

X509Certificate2 yourCertificate = null; 

foreach (Binding binding in yourSite.Bindings) 
{ 
    if (binding.Protocol == "https" && binding.EndPoint.ToString() == "127.0.0.1" /*your binding IP*/) 
    { 
     var store = new X509Store(StoreName.My, StoreLocation.LocalMachine); 
     store.Open(OpenFlags.ReadOnly); 
     yourCertificate = store.Certificates.Find(X509FindType.FindByThumbprint, ToHex(binding.CertificateHash), true)[0]; 
     break; 
    } 
} 

public static string ToHex(byte[] ba) 
{ 
    var hex = new StringBuilder(ba.Length * 2); 
    foreach (byte b in ba) 
    { 
     hex.AppendFormat("{0:x2}", b); 
    } 

    return hex.ToString(); 
} 
+0

Il pacchetto NuGet non è un funzionario Microsoft e deve essere evitato. –

+0

quel campo può essere impostato su chiunque. Controlla l'editore e vedrai. Questo assembly deve sempre essere aggiunto dalla cartella di installazione di IIS. –

+1

il percorso completo è '% windir% \ system32 \ inetsrv \ Microsoft.Web.Administration.dll'. Usalo per favore. –

4

Penso che la risposta di Camilo abbia un piccolo problema. Per quanto posso vedere (testato) il codice per trovare il certificato non funziona, perché System.Convert.ToBase64String(binding.CertificateHash) non restituisce un'identificazione personale del certificato valida.

La mia versione:

/// <summary> 
    /// Returns the https certificate used for a given local IIS website. 
    /// </summary> 
    /// <param name="sWebsite">Website url, e.g., "https://myserver.company.com"</param> 
    /// <returns>certificate, null if not found</returns> 
    private X509Certificate2 FindIisHttpsCert(string sWebsite) 
    { 
     Uri uriWebsite = new Uri(sWebsite); 
     using (ServerManager sm = new ServerManager()) 
     { 
     string sBindingPort = string.Format(":{0}:", uriWebsite.Port); 
     Binding bdBestMatch = null; 
     foreach (Site s in sm.Sites) 
     { 
      foreach (Binding bd in s.Bindings) 
      { 
      if (bd.BindingInformation.IndexOf(sBindingPort) >= 0) 
      { 
       string sBindingHostInfo = bd.BindingInformation.Substring(bd.BindingInformation.LastIndexOf(':') + 1); 
       if (uriWebsite.Host.IndexOf(sBindingHostInfo, StringComparison.InvariantCultureIgnoreCase) == 0) 
       { 
       if ((bd.Protocol == "https") && ((bdBestMatch == null) || (bdBestMatch.BindingInformation.Length < bd.BindingInformation.Length))) 
        bdBestMatch = bd; 
       } 
      } 
      } 
     } 
     if (bdBestMatch != null) 
     { 
      StringBuilder sbThumbPrint = new StringBuilder(); 
      for (int i = 0; i < bdBestMatch.CertificateHash.Length; i++) 
      sbThumbPrint.AppendFormat("{0:X2}", bdBestMatch.CertificateHash[i]); 

      X509Store store = new X509Store(bdBestMatch.CertificateStoreName, StoreLocation.LocalMachine); 
      store.Open(OpenFlags.ReadOnly); 
      X509Certificate2Collection coll = store.Certificates.Find(X509FindType.FindByThumbprint, sbThumbPrint.ToString(), true); 
      if (coll.Count > 0) 
      return coll[0]; 
     } 
     } 
     return null; // if no matching site was found 
    } 

Questa funzione è attiva anche se più https siti sono ospitati sullo stesso server (testato) e dovrebbe funzionare se il sito utilizza una porta diversa dalla 443 (non testato). Per ottenere informazioni su Binding, viene utilizzato %windir%\system32\inetsrv\Microsoft.Web.Administration.dll, come nella risposta di Camilo.

+0

Ho riscontrato lo stesso errore e il tuo codice funziona perfettamente! – Muis

Problemi correlati