使用Microsoft.Web.Administration以编程方式安装SSL证书

时间:2011-02-22 20:42:55

标签: c# ssl iis

因此 Microsoft.Web.Administration API非常易于用于为网站创建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();
}

但如果没有SSL证书,HTTPS绑定就毫无意义。如何使用此API以编程方式选择证书文件并将其与HTTPS绑定一起使用?

7 个答案:

答案 0 :(得分:7)

有一个方法重载,用于添加将正确添加证书到HTTP.sys的Bindings,请参阅: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

答案 1 :(得分:6)

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

答案 2 :(得分:6)

如果您需要证书哈希值(即具有各种SSL证书的单台计算机上的多个IP),Helephant的答案是最好的,您将需要知道如何获取证书/哈希值。下面的几行演示了如何找到信息,因为MSDN文档对于这个主题来说太差了。

您无法使用ServerManager.OpenRemote()远程更新SSL绑定 - 似乎存在此错误。 Appcmd也无济于事。

如果要将字节字符串转换回字节数组(如果知道哈希值),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();
    }
}

示例输出:

  

MY:
  www.awesomesite.com - cc2b5fc8216a949b58aadc21089c12b2c090f6bd

答案 3 :(得分:1)

命名空间不包含此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();

答案 4 :(得分:0)

添加Taylor 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()
...

上面的代码段对于更新证书非常有用,无需删除整个绑定。我已将它用于在本地和远程计算机上添加和更新ssl绑定。

感谢Bird先生提供WinAPI参考资料。

答案 5 :(得分:0)

如果你在这里登陆并希望使用PowerShell来实现这一目标,我会提出一个相当完整的答案here。最简单的答案是,如果您知道要使用的证书的哈希就是这样做:

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

答案 6 :(得分:0)

我觉得在this答案中强调Devator的评论很重要。似乎存在一个错误,阻止了证书更改,如果没有看到此注释,我将永远无法解决它。

如果将绑定信息设置为其自身,则会导致IIS绑定证书。一个简单的示例如下所示:

binding.BindingInformation = binding.BindingInformation;