IIS中的TLS互认证,无需重新协商



我正在托管一个web应用程序,该应用程序使用TLS对所有连接进行相互(双向)认证。我的web应用程序托管在Windows Server 2012上的IIS 8,它在IIS中配置为需要SSL,也需要客户端证书。当我从浏览器访问web应用程序时,提示我输入证书,一切似乎都很好。

然而,当我查看数据包捕获时,我看到TLS会话开始为单向身份验证会话,然后发送请求,然后会话被重新协商为双向身份验证会话,然后响应在此双向身份验证会话中发送。

这是不可接受的,原因如下:


    请求不是通过双向认证的TLS连接发送的。
    这将无缘无故地增加一个额外的TLS会话协商。
  1. 验证使用双向身份验证是困难的,因为双向身份验证握手消息在初始的单向身份验证会话中被加密
  2. TLS会话重新协商有安全漏洞,除非你正确设置。

我的猜测是IIS需要知道你要访问哪个站点,然后它才能应用适当的SSL设置,所以它从一个"默认的"单向身份验证会话开始,在它收到请求后,它决定它需要使用双向身份验证。因为我在IIS上托管的所有东西都需要双向身份验证,所以我希望这是"默认"行为。是否有一些方法来编写web应用程序或配置IIS(或Windows Server 2012)始终以2路身份验证TLS会话开始?

在http://technet.microsoft.com/en-us/security/bulletin/MS10-049找到答案。它没有列出IIS 8,但IIS 7的修复似乎有效:

对于IIS 7:

将以下文本保存到名为Enable_SSL_Renegotiate_Workaround.js

的文件中
// replace 1 on this line with the number of the web site you wish to configure
var vdirObj=GetObject("IIS://localhost/W3svc/1");
WScript.Echo("Value of SSLAlwaysNegoClientCert Before: " + vdirObj.SSLAlwaysNegoClientCert);
vdirObj.Put("SSLAlwaysNegoClientCert", true);
vdirObj.SetInfo();
WScript.Echo("Value of SSLAlwaysNegoClientCert After: " + vdirObj.SSLAlwaysNegoClientCert);

在提升的/administrator命令提示符下运行以下命令:

cscript.exe enable_ssl_renegotiate_workaround.js

juhraffe的回答确实有效,但也让我发现了一个看起来更简洁的解决方案。

在部署过程中,我们使用Network Configuration实用程序

将证书绑定到端口
netsh http add sslcert ipport=0.0.0.0:443 certhash=f882031933dc66a88993d5b5c326ed21b2ea8779 appid={4dc3e166-e14b-4a21-b022-59fc669b0914} 

显然可以添加一个额外的标志,它将达到与juhraffe的解决方案中描述的相同的效果

这就是我们如何修改命令
netsh http add sslcert ipport=0.0.0.0:443 certhash=f882031933dc66a88993d5b5c326ed21b2ea8779 appid={4dc3e166-e14b-4a21-b022-59fc669b0914} clientcertnegotiation=enable

最新更新