java keystore 實作ssl雙向認證【客戶端為php和java】

巴扎黑
發布: 2016-11-09 14:30:51
原創
2159 人瀏覽過

1.先搭建server端環境:

準備工作:tomcat6、jdk7、openssl、javawebservice測試項目一個

2.搭建過程:

參考http://blog.csdn.net/chow__zh/article/details/article/details/ 8998499

 1.1產生服務端憑證

keytool -genkey -v -alias tomcat -keyalg RSA -keystore D:/SSL/server/tomcat.keystore -dname "CN=127.0.0.1,OUzlj,O L=Peking,ST=Peking,C=CN" -validity 3650 -storepass zljzlj -keypass zljzlj

 

說明:
keytool 是JDK提供的憑證產生工具,所有參數的請參考證書
-v 詳細資料
-alias tomcat 以”tomcat」作為該證書的別名。這裡可以根據需要修改
-keyalg RSA 指定演算法
-keystore D:/SSL/server/tomcat.keystore 保存路徑及檔名
-dname "CN=127.0.0.1,OU=zlj,O=zlj,L=Peking ,ST=Peking,C=CN" 證書發行者身份,這裡的CN要與發布後的訪問域名一致。但由於我們是自己發行的證書,如果在瀏覽器訪問,仍然會有警告提示。
-validity 3650憑證有效期,單位為天
-storepass zljzlj 憑證的存取密碼
-keypass zljzlj 憑證的私鑰
    1.2 產生客戶端憑證keyalg RSA ‐ storetype PKCS12 ‐keystore D:/SSL/client/client.p12 ‐dname "CN=client,OU=zlj,O=zlj,L=bj,ST=bj,C=CN" ‐validity 3650 ‐storepassclient ‐store
說明:
    參數說明同上。這裡的-dname 憑證發行者身分可以和前面不同,到目前為止,這2個憑證可以沒有任何關係。下面要做的工作就是建立2者之間的信任關係。
    1.3 匯出用戶端憑證 
      1.3 匯出用戶端憑證 
    執行指令:
keytool ‐export ‐alias client ‐keystore D:/SSL/client/client.p12 ‐store ‐keystore D:/SSL/client/client.p12 ‐storeclicor 12cliclients ‐
說明:
-export 執行匯出
-file 匯出檔案的檔案路徑
    1.4 將客戶端憑證加入服務端憑證信任清單 
    執行指令:
keytool ‐import ‐alias cliclients 執行指令:
keytool ‐import ‐alias cliclient:dalias clis/files/fileo/Vage/fileo. .cer ‐keystore D:/SSL/server/tomcat.keystore ‐storepass zljzlj
說明:
參數說明同前。這裡提供的密碼是服務端憑證的存取密碼。
    1.5 匯出服務端憑證 
    執行指令:
keytool -export -alias tomcat -keystore D:/SSL/server/tomcat.keystore -storepass zljzlj -rfc -file D:/SSL/server/tomcat.keystore -storepass zljzlj -rfc -file D:/SSL/server//file.把服務端憑證導出。這裡提供的密碼也是服務端憑證的密碼。
    1.6 產生客戶端信任清單 
    執行指令:
keytool -import -file D:/SSL/server/tomcat.cer -storepass zljzlj -keystore D:/SSL/client/cliclient.
讓用戶端信任服務端憑證
2. 設定服務端為只允許HTTPS連線
    2.1 設定Tomcat 目錄下的/conf/server.xml 
Xml程式碼  收藏程式碼            maxThreads="150" scheme="https" secure="true" clientAuth="true"     
       keystorePass ="zljzlj" truststoreFile="D:/SSL/server/tomcat.keystore"    
       truststorePass="zljzlj" />   
,如果存在的註解的預設連接埠443,請修改這裡的port參數。其中的clientAuth="true" 指定了雙向憑證認證。
2.將client.p12匯入瀏覽器個人憑證項目。

此時輸入https://127.0.0.1:8443/會出現選擇證書,點選會提示https頁面不安全是否繼續,點繼續。到此服務端建置完成。

3.java呼叫server端直接上程式碼:

package test;
import javax.xml.namespace.QName;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
/**
 * 
 * @author gshen
 *
 */
public class TestEcVoteNotice {
 public static void main(String [] args) throws Exception {  
   System.setProperty("javax.net.ssl.trustStorePassword","zljzlj");    
   System.setProperty("javax.net.ssl.keyStoreType","PKCS12") ;    
   System.setProperty("javax.net.ssl.keyStore","D:/SSL/client/client.p12") ;    
   System.setProperty("javax.net.ssl.keyStorePassword","client") ;          
       System.setProperty("javax.net.debug", "all");
       
     //wsdl地址
String endpoint = "https://192.168.1.146:8443/pro/ws/getInfoService?wsdl";
//http://jarfiles.pandaidea.com/ 搜索axis.jar并下载,Service类在axis.jar
Service service = new Service();
//http://jarfiles.pandaidea.com/ 搜索axis.jar并下载,Call类在axis.jar
Call call = null;
try {
call = (Call) service.createCall();
//设置Call的调用地址
call.setTargetEndpointAddress(new java.net.URL(endpoint));
//根据wsdl中 <wsdl:import location="https://192.168.10.24:8443/ShinService/HelloWorld?wsdl=HelloService.wsdl" 
//namespace="http://server.cxf.shinkong.cn/" /> ,
//<wsdl:operation name="findALL">
call.setOperationName(new QName("http://ws.task.xm.com/","sayHello"));  
//参数1对应服务端的@WebParam(name = "tableName") 没有设置名称为arg0
call.addParameter("id", XMLType.SOAP_STRING, javax.xml.rpc.ParameterMode.IN);
           //调用方法的返回值
           call.setReturnType(org.apache.axis.Constants.XSD_STRING);  
           //调用用Operation调用存储过程(以服务端的方法为准)
String res = (String) call.invoke(new Object[] {"1"});  //调用存储过程
System.out.println(res);
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
     }  
}
登入後複製

 直接命令列運行或右鍵run as ,server端專案中我直接做了log列印,只要呼叫就會有列印。執行後

請看附件。

重點來了,接下來是php呼叫server,php的soapClient只識別DER、PEM或者ENG格式的證書,所以必須要把client.p12轉換為php可識別的pem文件,這時用到了openssl,首先進入cmd指令行,敲入以下程式碼

Java程式碼  

openssl pkcs12 -in D:\SSL\client\client.p12 -out D:\SSL\client\client-cer.pem -clcerts
登入後複製

 如果提示openssl指令不辨識則是你沒安裝openssl ,如果執行成功會提示你先輸入client.p12的密碼,輸入後會讓你輸入匯出的cer.pe的密碼,輸入後大功告成,client-cer.pem產生成功! 。

這時上php代碼:

Php代碼  

$params = array(&#39;id&#39; => &#39;2&#39;);  
  
    $local_cert = "./client-cer.pem";  
    set_time_limit(0);  
    try{  
        //ini_set("soap.wsdl_cache_enabled", "0"); // disabling WSDL cache  
        $wsdl=&#39;https://192.168.1.146:8443/pro/ws/getInfoService?wsdl&#39;;  
    //  echo file_get_contents($wsdl);  
          
        $soap=new SoapClient($wsdl,   
                    array(  
                        &#39;trace&#39;=>true,  
                        &#39;cache_wsdl&#39;=>WSDL_CACHE_NONE,   
                        &#39;soap_version&#39;   => SOAP_1_1,   
                        &#39;local_cert&#39; => $local_cert, //client证书信息  
                        &#39;passphrase&#39;=> &#39;client&#39;, //密码  
                       // &#39;allow_self_signed&#39;=> true  
                    )  
                );  
        $result=$soap->sayHello($params);  
        $result_json= json_encode($result);  
        $result= json_decode($result_json,true);  
        echo &#39;结果为:&#39; . json_decode($result[&#39;return&#39;],true);  
    }catch(Exception $e) {  
        $result[&#39;success&#39;] = &#39;0&#39;;  
        $result[&#39;msg&#39;] = &#39;请求超时&#39;;  
        echo $e->getMessage();  
    }  
    echo &#39;>>>>>>>>>>>&#39;;
登入後複製

 直接运行,也会出现附件中的结果,打完收工,憋了我整整三天时间,终于搞定了。


相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!