如何通过代码将现有的 SSL 证书分配给新的 IIS 站点?

How to assign an existing SSL certificate to a new IIS site through code?

我正在为测试环境开发一个简单的工具,我必须在其中通过 C# 代码设置几十个站点。因此,我在一个数组中有一个(子)域名(和其他属性)列表,我 运行 通过它来创建具有绑定的站点。这工作正常,除了我需要从商店绑定正确的 SSL 证书的 HTTPS 绑定。无论出于何种原因,所有站点最终都具有相同的证书。
代码相对简单。我首先像这样打开证书存储:

var store = new X509Store("MY", StoreLocation.LocalMachine);
store.Open(OpenFlags.OpenExistingOnly);

然后我为每个域找到 Certificate.Subject.EndsWith(domain.Domain) 也可以正常工作的证书。我显示哈希和名称,这些都是正确的。
然后我继续在端口 80 上创建具有基本绑定的每个域:

var site = manager.Sites.Add(domain.Name, "http", $"*:80:{domain.Domain}", domain.Folder);

如果找到证书,我也会绑定 HTTPS 连接:

site.Bindings.Add($"*:443:{domain.Domain}", domain.Certificate.GetCertHash(), "MY");

我还将哈希值写入控制台只是为了确保我有正确的值!然后 manager.CommitChanges(); 被调用以提交添加的站点。
然后我在 IIS 中检查附加了哪个证书,结果证明是错误的!所以每个站点都有一个证书错误,我不明白为什么会出错,因为一切似乎都是正确的。
因此,在提交之后,我再次通过枚举控制台的绑定来打印散列,它仍然显示正确的散列。这真的很烦人!
至于确实被选中的证书......它似乎是我列表中最后一个域的证书。但为什么它被分配给所有其他绑定?
这是 IIS 管理器中的错误吗?


一个小发现:我去了 IIS 并将证书更改为正确的证书。这会导致 IIS 中出现此消息:

这很有趣,因为当我单击“是”时,它将更改所有站点的证书。如果我单击“否”,那么我将返回到编辑对话框,这样就不会解决任何问题。不认为它相关,虽然...

笨蛋!笨蛋!哑的!解决了...

site.Bindings.Add($"*:443:{domain.Domain}", domain.Certificate.GetCertHash(), "MY", SslFlags.Sni);

最后是 SslFlags.Sni 标志,作为第 5 个参数,它起到了作用。它代表“服务器名称指示”,呃!如果您通过域名绑定证书,显然您需要它...
这么点小事也能这么烦人...