SSL原理及應用(3).NET開發中處理HTTPS
在ASP.NET、SQL Server、WCF等通信領域,微軟都提供了基於SSL的安全保護機制。遺憾的是,.NET並沒有對SSL協議本身提供像TCP、UDP這樣的基礎網絡協議的編程性支持。如果想從協議的角度處理SSL通信或者想構建完整的SSL框架,那么.NET幫不上你,但是還有選擇,許多第三方安全通信的項目提供了支持,比如OpenSSL。這不意味着我們在此領域將無所作為,第6章介紹了.NET中操作數字證書的兩個類:
q System.Security.Cryptography.X509Certificates.X509Certificate2類
q System.Security.Cryptography.X509Certificates.X509Store類
在Web開發中,SSL通信由瀏覽器和Web服務器來實現通信細節。封裝了HTTP協議的WebRequest、WebResponse等類提供了處理HTTPS請求的能力。當我們在程序中向HTTPS鏈接發送請求的時候,可以獲取服務器返回的證書。
請求HTTPS鏈接
當使用WebRequest類請求HTTPS鏈接的時候,在操作上和請求普通的HTTP鏈接沒什么不同。代碼清單8-1演示了如何獲取一個HTTPS鏈接的方法。
代碼清單 8-1獲取HTTPS鏈接
try
{
Uri uri = new Uri("https://www.sample.com/https.aspx");
WebRequest http = HttpWebRequest.Create(uri);
HttpWebResponse response = (HttpWebResponse)http.GetResponse();
Stream stream = response.GetResponseStream();
}
catch(UriFormatException e)
{
Console.WriteLine("無效的URL");
}
catch(IOException e)
{
Console.WriteLine("連接失敗");
}
代碼清單8-1中,通過HttpWebRequest對象的Create方法創建一個簡單的HTTPS請求,並反回一個HttpWebResponse對象。
說明 HttpWebRequest類對WebRequest中定義的屬性和方法提供支持,在使用HttpWebRequest對象向HTTP服務器發起請求時請不要使用HttpWebRequest對象的構造函數,而應該使用WebRequest.Create()方法來初始化新的HttpWebRequest對象。如果統一資源標識符方案是"http://"或"https://"時,Create()則返回HttpWebResponse對象。
證書信息的獲取與證書加載
在代碼清單8-1的基礎上,只需略加修改就可以讓程序適應需要提交客戶端證書的情況。如代碼清單8-2所示。
碼清單8-2 證書信息的獲取與證書加載
public void Test()
{
Uri uri = new Uri("https://www.sample.com/https.aspx");
HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(uri);
X509Certificate cer = X509Certificate.CreateFromCertFile("證書文件地址");
httpRequest.ClientCertificates.Add(cer);
HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();
Stream stream = response.GetResponseStream();
}
在代碼清單8-2中,首先創建一個X509Certificate對象,把它添加到WebRequest的ClientCertificates集合中。我們的證書一定要保護密鑰信息。
在服務器端,可以從客戶端請求的上下文中獲取客戶端提交的證書。
在Asp.NET中,可以通過下面的代碼來獲取證書信息:
Request.ClientCertificate(key[SubField])
在上面的代碼中,Key指定要獲取證書字段的名稱,不同的Key值具有不同的含義,SubField為可選字段。Key具體信息如表8-2所示。
表8-2 Request.ClientCertificate的Key值信息
值 |
意義 |
Certificate |
ASN.1 格式的二進制流字符串,即完整的證書內容 |
Flags |
一組標志,提供其他客戶端證書信息。可以設置:ceCertPresent(當前的客戶端證書)和ceUnrecognizedIssuer(該鏈接上來自未知的發行者的最后一個證書) |
Issuer |
包含子字段值的列表的字符串,此列表包含證書頒發者的信息。若該值在無SubField項的情況下指定,則ClientCertificate集合返回一個以逗號分隔的子字段列表。例如:C=US, O=Verisign等 |
SerialNumber |
包含證書的序列號的字符串,序列號以連字符(-)分隔的16進制ASCII碼表示,如04-67-F3-02 |
Subject |
包含子字段值的列表的字符串,此列表包含有關證書的主題信息。若該值在無SubField項的情況下指定,則 ClientCertificate 集合返回一個以逗號分隔的子字段列表。例如,C=US, O=Verisign等 |
ValidFrom |
指定證書何時有效。此日期遵循VBScript格式並隨國家(地區)設置而變化。例如,在美國可表示為9/26/96 11:59:59 PM |
ValidUntil |
指定證書何時到期 |
SubField用於按Subject或Issuer關鍵字檢索單獨的字段。此參數作為一個后綴添加到Key參數中,如IssuerO或SubjectCN。表8-3列出了一些通用的SubField值。
表8-3 SubField支持的參數和意義
值 |
意義 |
C |
指定原國家(地區)名 |
CN |
指定公用用戶名(此子字段僅同 Subject 關鍵字一起使用) |
GN |
指定給定的名稱 |
L |
指定所在地 |
O |
指定公司或組織名稱 |
OU |
指定機構的名稱 |
S |
指定州或省 |
T |
指定此人或組織的頭銜 |
根據表8-2和表8-3的說明,可以獲取關於客戶端證書的完整信息,這里不再演示。
----------------------注:本文部分內容改編自《.NET 安全揭秘》