Установить сертификат SSL с помощью Microsoft.Web.Administration

Таким образом, API Microsoft.Web.Administration очень прост в использовании для создания привязок HTTP и HTTPS для сайтов:

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

Но привязка HTTPS не имеет смысла без сертификата SSL. Как я могу программно выбрать файл сертификата и использовать его с привязкой HTTPS, используя этот API?

Ответ 1

Существует перегрузка метода для добавления привязок, которые правильно добавят сертификат в HTTP.sys: http://msdn.microsoft.com/en-us/library/bb355650(v=VS.90).aspx

Дополнительно вы можете установить настройки привязки:

binding.CertificateHash и binding.CertificateStoreName и при его компиляции будут правильно регистрироваться с помощью HTTP.sys: http://msdn.microsoft.com/en-us/library/microsoft.web.administration.binding_properties(v=VS.90).aspx

Ответ 2

Поскольку ответ Helephant является лучшим, если вам нужны хэши сертификатов (например, несколько IP-адресов на одной машине с различными сертификатами SSL), вам нужно знать, как получить сертификаты/хэши. Несколько строк ниже демонстрируют, как найти информацию, поскольку документация MSDN настолько бедна для этого объекта.

Вы не можете удаленно обновлять привязку SSL с помощью ServerManager.OpenRemote() - похоже, ошибка связана с этим. Appcmd тоже не поможет.

Если вы хотите преобразовать байтовую строку обратно в массив байтов (если вы знаете хэш), здесь как.

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

Пример вывода:

MY:
www.awesomesite.com - cc2b5fc8216a949b58aadc21089c12b2c090f6bd

Ответ 3

Метод Bindings.Add() имеет перегрузку для передачи в сертификате SSL. Если у вас уже есть сертификат SSL, вы можете выбрать его из хранилища сертификатов SSL следующим образом:

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

После запуска кода вы можете проверить, работает ли он, выполнив это из командной строки:

netsh http show sslcert

Ответ 4

Пространство имен не содержит API для этого, поэтому вы должны использовать его ConfigurationMethod для вызова расширения для Win API, который выполняет эту функцию. Что-то вроде:

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

Ответ 5

Добавление в комментарий Тейлора Берда, но с помощью 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()
...

Вышеприведенный фрагмент кода полезен для обновления сертификатов без необходимости удаления всей привязки. Я использовал его для добавления и обновления привязок ssl на локальных и удаленных машинах.

Спасибо Mr. Bird за предоставление справки WinAPI.

Ответ 6

Если вы приземлились здесь и хотите использовать PowerShell для этого, я поставил здесь довольно полный ответ . Самый простой ответ, если вы знаете, хэш сертификата, который вы хотите использовать, заключается в следующем:

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