最近有個項目要調用客戶用java寫的帶https的webservice,對方提供了證書檔案 test.pfx,我這裡調用方式如下:
//webservice代理類
SvcService svc = newSvcService();//證書檔案路徑
string filePath = ConfigurationManager.AppSettings["pfxUrl"];
X509Certificate cert= new System.Security.Cryptography.X509Certificates.X509Certificate(filePath, "123456");//将證書添加用戶端證書集合
svc.ClientCertificates.Add(cert);//webservice調用代碼...
測試調用報錯:請求被中止: 未能建立 SSL/TLS 安全通道,于是趕緊google,找到如下解決方案:
在webservice代理類的構造函數中添加下面的代碼,繞過伺服器證書驗證。
public static bool CheckValidationResult(objectsender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{return true;
}publicSvcService()
{
ServicePointManager.Expect100Continue= true;
ServicePointManager.SecurityProtocol=SecurityProtocolType.Ssl3;
ServicePointManager.ServerCertificateValidationCallback= newRemoteCertificateValidationCallback(CheckValidationResult);this.Url = ConfigurationManager.AppSettings["host"];
}
本地vs環境下再試,好了!調用成功!不報錯了!于是趕緊釋出到IIS伺服器上試一下,郁悶的是伺服器上居然報錯,還是這個未能建立 SSL/TLS 安全通道!
于是繼續google,找到下面的解決方法:
1.将用戶端證書檔案導入到本地計算機賬戶下的個人存儲區。
3.安裝後一般是在C:\Program Files\Windows Resource Kits\Tools這個路徑下面。 進入cmd 執行如下指令:winhttpcertcfg -g -c LOCAL_MACHINE\MY -s "test" -a "NetworkService"
這裡解釋一下這幾個參數的含義:
-g 是grant授權的意思,将該證書的使用權限授予某個使用者
-c 是certstore證書存儲區,指定 本地計算機/目前使用者下的證書存儲區位置,我們這裡是MY,個人存儲區
-s 是subjectstr 用于模糊比對證書的一個字元串,我們這裡用證書檔案名 test
-a 是account要授權的使用者帳号
這裡要注意的是授權賬戶,IIS6下面一般用的是NetworkService,如果你用的IIS7,必須要保證你網站所用的應用程式池的 "辨別"和要授權的賬戶一緻。
執行成功之後,會列出模糊比對出的證書清單和已經授權的賬戶。
然後程式代碼做如下更改:
//webservice用戶端代理類
SvcService svc = newSvcService();//打開本地計算機下的個人證書存儲區
X509Store certStore = newSystem.Security.Cryptography.X509Certificates.X509Store(StoreName.My, StoreLocation.LocalMachine);
certStore.Open(OpenFlags.ReadOnly);//根據名稱查找比對的證書集合,這裡注意最後一個參數,傳true的話會找不到
X509Certificate2Collection certCollection = certStore.Certificates.Find(System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName, "test", false);//将證書添加至用戶端證書集合
svc.ClientCertificates.Add(certCollection[0]);//webservice調用代碼
再測試了一下,調用正常!至此這個問題算圓滿解決了!
總結:我們導入的用戶端證書并不是所有的賬戶都能通路和使用,因為我們的開發伺服器也就是VS自帶的伺服器預設使用目前使用者,而目前使用者具有使用證書的權限,是以我們在本地調試的時候,一切正常。當我們将網站部署到IIS後,由于IIS的使用的是内置賬戶不具有證書的使用權限,是以就出現了上述問題,這個時候我們隻需用winhttpcertcfg這個工具給指定賬戶授予使用證書的權限,就可以正常調用啦!