Saltar al contenido

Cómo obtener un certificado de un enlace específico C#

Recuerda que en la informática cualquier problema suele tener varias soluciones, de igual modo aquí compartiremos lo más óptimo y eficiente.

Solución:

Los certificados en sí mismos no contienen absolutamente ninguna información sobre los enlaces utilizados en IIS, por lo que no puede recuperar los certificados de la máquina y esperar que tengan algo relacionado con IIS. Tendría que consultar esa información de IIS.

Para hacer esto, deberá agregar una referencia a la biblioteca que se puede encontrar en %windir%system32inetsrvMicrosoft.Web.Administration.dll (nota: se debe instalar IIS 7 o posterior). Después de esto, puede hacer algo como lo siguiente para obtener el certificado:

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();

Creo que la respuesta de Camilo tiene un pequeño problema. Por lo que puedo ver (probado) el código para encontrar el certificado no funciona, porque System.Convert.ToBase64String(binding.CertificateHash) no devuelve una huella digital de certificado válida.

Mi version:

    /// 
    /// Returns the https certificate used for a given local IIS website.
    /// 
    /// Website url, e.g., "https://myserver.company.com"
    /// certificate, null if not found
    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) 
            
          
        
        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
    

Esta función también funciona si varios sitios https están alojados en el mismo servidor (probado) y debería funcionar si el sitio usa un puerto diferente al 443 (no probado). Para obtener información vinculante, %windir%system32inetsrvMicrosoft.Web.Administration.dll se usa, como en la respuesta de Camilo.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *