IIS6與IIS7在編程實現HTTPS綁定時的細微差別

來源:互聯網
上載者:User

標籤:

本文章其實最主要資訊是:

問題出在那個小小的*號上——IIS6中不支援萬用字元,第一部分為空白時表示(All Unsigned),而IIS7中同時支援空或萬用字元的寫法,如果為空白則自動轉為*:443:,我們將調用行改為:AddHttpsBinding(":443:", "MY", hash);後,問題解決。

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

 

最近剛剛解決了一個困擾了很久的問題,發出來大家共用一下。
問題很簡單,就是我們在做一個自動部署網站的程式,需要同時支援在IIS6與IIS7實現HTTPS,也就是要編程實現增加HTTPS綁定,開始的時候My Code是這樣的:

         private void WriteBinaryArrayToDirectoryEntry(PropertyValueCollection entry, byte[] data)
        {
            string[] 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);
        }

       public 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)”。

結果,我們只好把程式改成這樣:
        public 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);
後,問題解決。

IIS6與IIS7在編程實現HTTPS綁定時的細微差別

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.