2011-02-22 25 views
11

Así que la Microsoft.Web.Administration API es muy fácil de usar para crear enlaces de HTTP y HTTPS para sitios:Instalar certificado SSL mediante programación utilizando Microsoft.Web.Administration

using (ServerManager manager = new ServerManager()) 
{ 
    Site site = manager.Sites[siteName]; 
    site.Bindings.Clear(); 
    site.Bindings.Add("*:80:", "http"); 
    site.Bindings.Add("*:443:", "https"); 

    manager.CommitChanges(); 
} 

Pero los enlace HTTPS es bastante sin sentido sin el certificado SSL. ¿Cómo puedo elegir programáticamente un archivo cert y usarlo con el enlace HTTPS usando esta API?

Respuesta

7

Hay una sobrecarga de método para añadir enlaces que le darán el certificado de HTTP.sys correctamente, consulte: http://msdn.microsoft.com/en-us/library/bb355650(v=VS.90).aspx

Opcionalmente realidad se puede establecer la configuración de enlace:

vinculantes .CertificateHash y binding.CertificateStoreName y al confirmarlo se registrará correctamente con HTTP.sys: http://msdn.microsoft.com/en-us/library/microsoft.web.administration.binding_properties(v=VS.90).aspx

+1

Sé que esta es una vieja pregunta, pero he notado que si configuro los valores 'CertificateHash' y' CertificateStoreName' para el enlace y llamo 'CommitChanges' todo supuestamente tiene éxito, pero el enlace no está establecido. No estoy seguro de por qué parece suceder. – Fizz

1

El espacio de nombre no contiene una API para esto, por lo que debe usar su ConfigurationMethod para invocar una extensión a la API de Windows que realiza esta función. Algo así como:

string certificateHash = <hash> 
string certificateStore = <storename> #my, localmachine, etc 

ConfigurationMethod method = binding.Methods["AddSslCertificate"]; 
ConfigurationMethodInstance mi = method.CreateInstance(); 
mi.Input.SetAttributeValue("certificateHash", certificateHash); 
mi.Input.SetAttributeValue("certificateStoreName", certificateStore); 
mi.Execute(); 
+0

De hecho descubrió que la API sí lo hace. Vea aquí: http://msdn.microsoft.com/en-us/library/bb355650(VS.90).aspx –

+0

Parece que CarlosAg también tiene el enlace en su respuesta. –

4

El método Bindings.Add() tiene una sobrecarga para pasar el certificado SSL. Si ya tiene un certificado SSL, puede seleccionarlo en el almacén de certificados SSL como esto:

var store = new X509Store(StoreName.My, StoreLocation.LocalMachine); 
store.Open(OpenFlags.OpenExistingOnly); 
var certificate = store.Certificates.Find(X509FindType.FindByThumbprint, the thumbprint for the key", true); 

var site = _mgr.Sites[name]; 
site.Bindings.Add("*:4043:", certificate[0].GetCertHash(), "MY"); 

Una vez que haya ejecutado el código, puede comprobar que se ha trabajado mediante la ejecución de esto desde la línea de comandos:

netsh http show sslcert 
6

como la respuesta de Helephant es el mejor si necesita los valores hash de certificado (es decir, varias direcciones IP en una sola máquina con varios certificados SSL), usted necesita saber cómo obtener los certificados/hashes. Las pocas líneas a continuación muestran cómo encontrar la información, ya que la documentación de MSDN es tan pobre para este tema.

No se puede actualizar de forma remota un enlace SSL utilizando ServerManager.OpenRemote() - parece haber un error con esto. Appcmd tampoco te ayudará.

Si desea convertir una cadena de bytes de nuevo en una matriz de bytes (si se conoce el hash), here's how.

static void Main(string[] args) 
{ 
    var store2 = new X509Store(StoreName.TrustedPublisher, StoreLocation.LocalMachine); 
    Console.WriteLine("TrustedPublisher:"); 
    PrintCerts(store2); 
    Console.WriteLine(); 

    Console.WriteLine("MY:"); 
    store2 = new X509Store(StoreName.My, StoreLocation.LocalMachine); 
    PrintCerts(store2); 
    Console.WriteLine(); 

    Console.WriteLine("CertificateAuthority:"); 
    store2 = new X509Store(StoreName.CertificateAuthority, StoreLocation.LocalMachine); 
    PrintCerts(store2); 
    Console.WriteLine(); 
} 

static string PrintHash(byte[] cert) 
{ 
    StringBuilder builder = new StringBuilder(); 

    foreach (byte b in cert) 
    { 
     builder.AppendFormat("{0:x2}", b); 
    } 

    return builder.ToString(); 
} 

static void PrintCerts(X509Store store) 
{ 
    store.Open(OpenFlags.OpenExistingOnly); 
    foreach (var cert in store.Certificates) 
    { 
     Console.Write("{0} - {1}", cert.FriendlyName, PrintHash(cert.GetCertHash())); 
     Console.WriteLine(); 
    } 
} 

Ejemplo de salida:

MI:
www.awesomesite .com - cc2b5fc8216a949b58aadc21089c12b2c090f6bd

0

Adding to Taylo comentario, pero utilizando de r Bird PowerShell:

... 
Write-Verbose ("Remove old certificate [ {0} ]... " -f $SiteHttpsBinding.GetAttributeValue("certificateHash")) 
$BindingMethod=$SiteHttpsBindings.Methods["RemoveSslCertificate"] 
$BindingMethodInstance=$BindingMethod.CreateInstance() 
$BindingMethodInstance.Execute() 
Write-Verbose ("Add new certificate [ {0} ]..." -f $AfterThumbprint) 
$BindingMethod=$SiteHttpsBindings.Methods["AddSslCertificate"] 
$BindingMethodInstance=$BindingMethod.CreateInstance() 
$BindingMethodInstance.Input.SetAttributeValue("certificateHash", $AfterThumbprint) 
$BindingMethodInstance.Input.SetAttributeValue("certificateStoreName", "My") 
$BindingMethodInstance.Execute() 
... 

El fragmento de código anterior es útil para actualizar los certificados sin necesidad de quitar toda la unión. Lo he usado para agregar y actualizar enlaces ssl en máquinas locales y remotas.

Gracias al Sr. Bird por el suministro de la referencia de WinAPI.

0

Si ha aterrizado aquí y quiere utilizar PowerShell para lograr esto, puse una respuesta bastante completa here. La respuesta más simple, si conoce el hash del certificado que desea utilizar es hacer esto:

cd IIS:\SslBindings 
get-item Cert:\LocalMachine\My\XFX2DX02779XFD1F6F4X8435A5X26ED2X8DEFX95 | New-Item 0.0.0.0!443 
Cuestiones relacionadas