【问题标题】:Install SSL certificate programmatically using Microsoft.Web.Administration使用 Microsoft.Web.Administration 以编程方式安装 SSL 证书
【发布时间】:2011-07-02 07:24:01
【问题描述】:

因此,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 绑定一起使用?

【问题讨论】:

  • 接受的答案不是高质量的答案。它缺少代码,并告诉您去其他地方寻找。它更接近评论而不是答案。我认为您应该考虑接受另一个答案。

标签: c# ssl iis


【解决方案1】:

我觉得在this 回答中突出 Devator 的评论很重要。似乎存在阻止证书更改发生的错误,如果没有看到此评论,我将永远无法解决它。

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

binding.BindingInformation = binding.BindingInformation;

【讨论】:

    【解决方案2】:

    如果您登陆这里并希望使用 PowerShell 来完成此任务,我会给出一个相当完整的答案 here。最简单的答案是,如果您知道要使用的证书的哈希值,请执行以下操作:

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

    【讨论】:

      【解决方案3】:

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

      上面的代码 sn-p 对于更新证书很有用,而无需删除整个绑定。我用它来添加和更新本地和远程机器上的 ssl 绑定。

      感谢 Bird 先生提供 WinAPI 参考。

      【讨论】:

        【解决方案4】:

        如果您需要证书哈希(即具有各种 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();
            }
        }
        

        示例输出:

        我的:
        www.awesomesite.com - cc2b5fc8216a949b58aadc21089c12b2c090f6bd

        【讨论】:

          【解决方案5】:

          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
          

          【讨论】:

            【解决方案6】:

            添加绑定的方法重载可以正确地将证书添加到 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

            【讨论】:

            • 我知道这是一个老问题,但我注意到如果我为绑定设置 CertificateHashCertificateStoreName 值并调用 CommitChanges 一切都应该成功,但绑定没有设置。不知道为什么会这样。
            • @Fizz:我不得不手动设置binding.BindingInformation = binding.BindingInformation;(尽管这看起来没有意义,但这会导致 IIS 实际绑定证书)。
            • @Devator 有任何线索为什么会这样吗?这也对我有用,虽然你是对的,但这没有意义。
            • 重要提示: 正如@Fizz 所指出的,您必须手动将 BindingInformation 设置回自身,才能实际设置 CertificateHash 和 CertificateStoreName(以及其他属性)。这对我来说似乎是一个错误,让我发疯,直到我意识到 Fizz 告诉我们要做什么。
            • 我尝试了这个并得到 HRESULT 0x80070520 指定的登录会话不存在。它可能已被终止。
            【解决方案7】:

            命名空间不包含用于此功能的 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();
            

            【讨论】:

            • 实际上发现API确实处理它。见这里:msdn.microsoft.com/en-us/library/bb355650(VS.90).aspx
            • 看起来 CarlosAg 在他的回答中也有链接。
            • 现在在 2020 年可以使用 IIS v10。我的大错误,3天扔垃圾,非常非常重要了解“mi.Input.SetAttributeValue("certificateStoreName", certificateStore);"当我自己制作时,如果在“certificateStoreName”中输入证书名称,这是我的大错误。正确的是 STORE 名称,而不是证书名称。
            猜你喜欢
            • 2012-09-29
            • 2011-09-11
            • 2011-07-16
            • 1970-01-01
            • 1970-01-01
            • 2010-11-28
            • 2012-10-09
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多