当前位置首页 > IIS知识

IIS6与IIS7在编程实现HTTPS绑定时的细微差别

阅读次数:399 次  来源:admin  发布时间:

本文章其实最主要信息是:

问题出在那个小小的*号上——IIS6中不支持通配符,第一部分为空时表示(All Unsigned),而IIS7中同时支持空或通配符的写法,如果为空则自动转为*:443:,我们将调用行改为:
AddHttpsBinding(":443:", "MY", hash);
后,问题解决。

文章转自:http://linwx1978.blog.163.com/blog/static/1504106920111281434624/

最近刚刚解决了一个困扰了很久的问题,发出来大家共享一下。

问题很简单,就是我们在做一个自动部署网站的程序,需要同时支持在IIS6与IIS7实现HTTPS,也就是要编程实现增加HTTPS绑定,开始的时候我的代码是这样的:

rivate void WriteBinaryArrayToDirectoryEntry(PropertyValueCollection entry, byte[] data)

{

tring[] arrStr = new string[data.Length]

for (int i = 0; i < data.Length; i++)

{

arrStr[i] = String.Format("{0:x2}", data[i])

}

object[] arrObj = new object[arrStr.Length]

arrStr.CopyTo(arrObj, 0)

entry.Clear()

entry.Add(arrObj)

}

ublic void AddHttpsBinding(string binding, string nameStore, byte[] hash)

{

DirectoryEntry entry = new DirectoryEntry("IIS://localhost/W3SVC/1");//指向Default Web Site

entry.Properties[”SecureBindings"].Clear()

entry.Properties["SecureBindings"].Add(binding)

WriteBinaryArrayToDirectoryEntry(entry.Properties["SSLCertHash"], hash)

entry.CommitChanges()

}

其中标出来的那一行需要注意,如果需要指向非缺省的网站就可能需要修改,当然,这是题外话。

调用如下:

AddHttpsBinding("*:443:", "MY", hash)

*:443:的意思是指定443端口,任意IP(All Unassigned IP)。

结果,在IIS7上运行良好,在IIS6及IIS5上就遇到了很多问题,HTTPS无法访问。

首先我们检查了HTTPS绑定,结果发现证书绑定失败。用Metabase Explorer检查/LM/W3SVC/1下应该有三项与HTTPS绑定有关的条目,分别是:

SecureBindings,指定端口、IP及HEADER信息。

SSLCertHash,指定目标证书的哈希值。

SSLStoreName,指定目标证书所在的目录。

绑定成功的情况下,这三个条目都应该出现,并且填入我们指定的值,但上述程序在IIS6上运行之后,只有前两个条目而没有SSLStoreName,导致HTTPS服务无法找到目标证书。

原因是,在IIS6中,必需设定SSLStoreName,而且还必需在设定SSLCertHash之前。但在IIS7中,SSLStoreName由系统自动设定,如果程序试图自行设定,系统会抛出异常:“A specified logon session does not exist. It may already have been terminated. (Exception from HRESULT: 0x80070520)”。

结果,我们只好把程序改成这样:

ublic void AddHttpsBinding(string binding, string nameStore, byte[] hash)

{

DirectoryEntry entry = new DirectoryEntry("IIS://localhost/W3SVC/1")

entry.Properties[”SecureBindings"].Clear()

entry.Properties[”SecureBindings"]Add(binding)

WriteBinaryArrayToDirectoryEntry(entry.Properties["SSLCertHash"], hash)

entry.CommitChanges()

if (TryGetValue("IIS://localhost/W3SVC/1", "SSLStoreName") == "")

{

entry.Properties["SSLStoreName"].Clear()

entry.Properties["SSLStoreName"].Add(nameStore)

WriteBinaryArrayToDirectoryEntry(entry.Properties["SSLCertHash"], hash)

entry.CommitChanges()

}

}

加上了蓝色的部分,在前面的设定结束之后,测试SSLStoreName是否为空,如果为空,则依次设定SSLStoreName和SSLCertHash。在IIS6和IIS7上测试均成功。

然后我们就遇到了第二个问题:现在IIS6上绑定是成功的,从IIS管理器上也可以看到绑定的证书信息了,但仍然无法用HTTPS访问,下载了一个微软的SSL工具SSL Diagnostics测试了一下,说绑定的IP与SSL的IP不符,可能有问题。于是我们打开IIS管理器,在网站上点击右键,到属性->Web Site页,点击Advanced,在Multiple SSL identities for this Web Site一栏中,发现IP Address一栏写的居然是255.255.255.255,果然有问题!手动将其改为(All Unsigned)之后,问题解决。

使用Metabase Explorer检查,发现SecureBindings中写的是:443:,也就是说,问题出在那个小小的*号上——IIS6中不支持通配符,第一部分为空时表示(All Unsigned),而IIS7中同时支持空或通配符的写法,如果为空则自动转为*:443:,我们将调用行改为:

AddHttpsBinding(":443:", "MY", hash)

后,问题解决。

上一篇:ubuntu下vmware6.5安装与卸载-Qzi
下一篇:Ubuntu在UEFI模式下正确进入grub菜单的方法