Nginx、SSL雙向認證、PHP、SOAP、Webservice、https

本文是1:1模式,N:1模式請參見新的一篇博客《SSL雙向認證(高清版)》

----------------------------------------------------- 我是分割線 ---------------------------------------------------------

標題太長了不知道該怎麼起,索性就把keyword列出來吧~

WebService的WS-*搞了一天沒搞定,看樣子PHP應該是徹底拋棄SOAP協議了,google翻爛了也沒找到什麼靠譜的解決方案。

合作方又不願意自己去實現加解密簽名那些東西,沒辦法,只好走https了,把這塊兒從應用層拋到更底層去。

但是通信中的數據安全分幾部分:保密性、不可篡改,不可抵賴

傳統的https調用只是對數據做了加密,解決了保密以及不可篡改問題,解決不了客戶端的身份驗證問題,或者叫不可抵賴性。

所以需要使用兩套證書的SSL雙向認證。

目前的Nginx對SSL雙向認證支持的比較好,配置很簡單:

        ……
        listen      443;
        server_name test.com;

        ssl on;
        ssl_certificate server.crt; //server端公鑰
        ssl_certificate_key server.key; //server端私鑰
        ssl_client_certificate client.crt; //client端公鑰
        ssl_session_timeout 5m;
        ssl_verify_client on; //開啓client驗證
        ……
        

其實就是在常規https配置基礎上增加了client端公鑰設置,以及開啓client驗證。(更多配置信息參考nginx官方文檔:http://wiki.nginx.org/HttpSslModule#ssl

服務端配好了後,原來的wsdl地址就需要通過https纔可訪問。但是,客戶端訪問時需要使用client端的證書。

先以curl測試,相關參數:

……
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何證書
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // 不檢查證書中域名
curl_setopt($ch, CURLOPT_VERBOSE, '1'); //開發模式,會把通信時的信息顯示出來
curl_setopt($ch, CURLOPT_SSLCERT, 'client.crt');  //客戶端crt
curl_setopt($ch, CURLOPT_SSLCERTPASSWD, '123456');  //客戶端證書密碼
curl_setopt($ch, CURLOPT_SSLKEY, 'client.key');  //客戶端key
curl_setopt($ch, CURLOPT_POST, false); //不能用POST
……
我使用的是nusoap實現的webservice服務端(具體參見《你喜歡SOAP嗎?反正我不喜歡!》),此時會看到wsdl中的綁定接口地址已經是443端口地址。

下面改用SOAP調用,PHP自帶的SoapClient就支持,只需設置如下header:

        ……
	$local_cert = "client.pem"; //包含crt和key內容的pem
        $header = array(
                'local_cert' => $local_cert, //client證書信息
                'passphrase'=> '123456' //密碼
                );
        $client = new SoapClient($wsdl, $header);
	……
需要注意的一點是:此時client.pem的內容需要包含證書以及私鑰信息,如下:

-----BEGIN CERTIFICATE-----
MIICdTCCAd4C……
-----END CERTIFICATE-----

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKB……
-----END RSA PRIVATE KEY-----
此時會發現仍然有如下報錯信息:

SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://test.com/soap_test.php?wsdl' : Premature end of data in tag html line 1
在google上翻到了一個哥們類似的遭遇,結果和我意料的一樣:事先取wsdl的時候soapclient根本沒有使用證書信息!

用curl抓下來保存成本地文件進行調用,一切OK~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章