Https協議的使用--服務器端和客戶端

文章內容

1.Web服務器(tomcat)端配置
2.客戶端(HttpClient)實現(Get/Post)

1.Web服務器(tomcat)端配置

1.1.服務器證書生成
這裏寫圖片描述

使用keytool按照提示創建一個證書,如果以後真正在產品環境中使用肯定要去證書提供商去購買,證書認證一般都是由VeriSign認證,中文官方網站:http://www.verisign.com/cn/,需要注意一下幾點:
1.密鑰庫口令
2.名字爲網站域名(後面通過修改host轉發)


命令:
keytool -genkey -alias aaronweb -keyalg RSA -keystore d:/keys/aaronweb

1.2.導出證書
導出的證書可以給響應的客戶端使用
這裏寫圖片描述


命令:
keytool -export -file d:/keys/waaronweb.crt -alias aaronweb -keystore D:/keys/aaronweb

1.3.創建私鑰(pem)(用於tomcat apr模式)
這裏寫圖片描述

這裏寫圖片描述


命令:
keytool -importkeystore -srckeystore D:\keys\aaronweb -destkeystore D:\keys\aaronweb.p12 -deststoretype PKCS12

openssl pkcs12 -in D:\keys\aaronweb.p12 -out D:\keys\aaronweb.pem -nodes

1.2.修改hosts文件
修改host使得在訪問域名aaron.web.com時實際訪問的是本地主機;
目錄:C:\Windows\System32\drivers\etc\hosts
添加:127.0.0.1 aaron.web.com

1.3.Web服務器創建和配置
1.在Eclipse中配置好Tomcat環境,添加一個新的Web服務器;
這裏寫圖片描述

2.修改服務器配置
這裏寫圖片描述

修改Server.xml配置:
添加SSLCertificateFile(導出證書crt文件地址),SSLCertificateKeyFile(生成的私鑰pem文件地址)
這裏寫圖片描述

3.服務器測試
通過Eclipse導入一個Web項目到先添加的tomcat服務器上,啓動服務器,在瀏覽器中測試;

注意端口地址8443或自定義
瀏覽器需要添加例外(證書不是公共平臺認證的)

這裏寫圖片描述

2.客戶端(HttpClient)實現(Get/Post)

2.0.準備

應爲需要測試Get、Post兩種方式,需要在web項目中添加測試用的servlet,比如:

public class HelloWorldServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
        PrintWriter out = res.getWriter();
        out.println("Hello, Brave new World!");
        out.close();
    }
}

2.1.忽略認證Https客戶端的實現

在很多情況下我們並不希望驗證服務器的證書信息,而需要忽略驗證的結果,特別是在接口調用上,所以,首先實現忽略驗證的Https客戶端,主要實現常用的Get和Post方法;

下面是具體的步驟:
(對於其中涉及到的相關概念可以參考之前的文章:http://blog.csdn.net/villare/article/details/75045496

1.首先我們繼承默認的HttpClient父類,爲了實現對上層的透明性,通過重寫類的構造方法,完成對HttpClient的配置;

public class SSLClient extends DefaultHttpClient{
    public SSLClient() throws Exception{
        super();
    }
}

2.由於Https爲有狀態的連接,所以首先需要設置上下文環境(Context),用於維護連接過程中的狀態;Java提供與Https相關的Context類;

SSLContext ctx = SSLContext.getInstance("TLS");

3.由於我們需要忽略對證書的檢查,所以需要實現X509TrustManager(證書信任管理器),重寫器中的主要驗證方法,達到忽略證書驗證的目的;並配置到Context中

X509TrustManager tm = new X509TrustManager() { 
            //該方法檢查客戶端的證書,若不信任該證書則拋出異常 
            @Override  
            public void checkClientTrusted(X509Certificate[] chain,  
                    String authType) throws CertificateException {  
            }  
            //該方法檢查服務器的證書,若不信任該證書同樣拋出異常
            @Override  
            public void checkServerTrusted(X509Certificate[] chain,  
                    String authType) throws CertificateException {  
            }  
            //返回受信任的X509證書數組
            @Override  
            public X509Certificate[] getAcceptedIssuers() {  
                return null;  
            }  
        };  
//初始化Context
ctx.init(null, new TrustManager[]{tm}, null);  

4.由於Https的數據傳輸爲加密傳輸,一般的socket傳輸不考慮數據是否加密,當然HttpClient提供了相關的實現,只需要創建對應的SocketFactory對象,並綁定對應的Context;

SSLSocketFactory ssf = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);  

5.在當前HttpClient中註冊Https模式,並綁定對應的SocketFactory;至此,通過此HttpCLient發送的Https請求就會使用當前SocketFactory和Context(包括其中的認證管理器);

ClientConnectionManager ccm = this.getConnectionManager();  
SchemeRegistry sr = ccm.getSchemeRegistry();  
sr.register(new Scheme("https", 8443, ssf)); 

6.在使用重寫的SSLClient時,與普通的HttpClient一樣;

HttpClient httpClient = new SSLClient(); 

2.2.檢查認證Https客戶端的實現

和忽略的方式唯一不同的是:證書認證管理器,如果忽略認證,我們在checkClientTrusted、checkServerTrusted和getAcceptedIssuers中都沒有包含具體的驗證邏輯或直接返回默認值;所以,如果需要驗證證書,只需要在其中實現相應的邏輯即可,如果認證不通過,直接拋出CertificateException 異常即可,由於,證書不同,驗證的方式也不同,具體的問題具體分析;

參考文章:輕鬆把玩HttpClient之配置ssl,採用繞過證書驗證實現https 龍軒

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