雙向驗證,在客戶機連接服務器時,客戶機驗證服務器的證書,服務器驗證客戶機的證書,鏈接雙方都要對彼此的數字證書進行驗證,保證這是經過授權的才能夠連接。
1. 生成服務器端的keystore和truststore文件:
1.1. 以jks格式生成服務器端包含Public key和Private Key的keystore文件,keypass與storepass務必要一樣,因為在tomcat server.xml中只配置一個password.
keytool -genkey -alias server -keystore serverKeystore.jks -keypass 123456 -storepass 123456 -keyalg RSA -keysize 512 -validity 365 -v -dname "CN = W03GCA01A,O = ABC BANK,DC = Server Https,DC = ABC,OU = Firefly Technology And Operation"
1.2. 從keystore中導出別名為server的服務端證書.
keytool -export -alias server -keystore serverKeystore.jks -storepass 123456 -file server.cer
1.3. 將server.cer導入客戶端的信任證書庫clientTruststore.jks。
keytool -import -alias trustServer -file server.cer -keystore clientTruststore.jks -storepass 123456
2. 生成客戶端的keystore和truststore文件:
1.1. 以jks格式生成服務器端包含Public key和Private Key的keystore文件。
keytool -genkey -alias client -keystore clientKeystore.jks -keypass 123456 -storepass 123456 -keyalg RSA -keysize 512 -validity 365 -v -dname "CN = W03GCA01A,O = ABC BANK,DC = Client Https,DC = ABC,OU = Firefly Technology And Operation"
1.2. 從keystore中導出別名為client的客戶端證書.
keytool -export -alias client -keystore clientKeystore.jks -storepass 123456 -file client.cer
1.3. 將client.cer導入服務端的信任證書庫serverTruststore.jks。
keytool -import -alias trustClient -file client.cer -keystore serverTruststore.jks -storepass 123456
服務器端: serverKeystore.jks serverTruststore.jks
客戶端: clientKeystore.jks clientTruststore.jks
3. 在tomcat 配置server.xml
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="true" sslProtocol="TLS" keystoreFile="keystore/serverKeystore.jks" keystorePass="123456" truststoreFile="keystore/serverTruststore.jks" truststorePass="123456" />
4. 客戶端代碼
package com.ssl.http; import java.io.File; import java.io.FileInputStream; import java.security.KeyStore; import java.security.KeyStoreException; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; /** * * @author kevin * */ public class ClientTwoWaySSL { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub DefaultHttpClient httpclient = new DefaultHttpClient(); KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); FileInputStream keyStoreIn = new FileInputStream(new File( "com/ssl/http/clientKeystore.jks")); FileInputStream trustStoreIn = new FileInputStream(new File( "com/ssl/http/clientTruststore.jks")); try { keyStore.load(keyStoreIn, "123456".toCharArray()); trustStore.load(trustStoreIn, "123456".toCharArray()); } finally { keyStoreIn.close(); trustStoreIn.close(); } SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore, "123456", trustStore); Scheme sch = new Scheme("https", socketFactory, 8443); httpclient.getConnectionManager().getSchemeRegistry().register(sch); HttpGet httpget = new HttpGet("https://w03gca01a:8443/"); System.out.println("Request:" + httpget.getRequestLine()); HttpResponse response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); if (entity != null) { System.out.println("Response content length: " + entity.getContentLength()); } if (entity != null) { entity.consumeContent(); } httpclient.getConnectionManager().shutdown(); } }
備注:
A. 如出現如下error,請配置C:\WINDOWS\system32\drivers\etc\hosts, 將“127.0.0.1 w03gca01a” 加在hosts文件中
# executing requestGET https://w03gca01a/ HTTP/1.1 # Exception in thread "main" javax.net.ssl.SSLException: hostname in certificate didn't match: <w03gca01a> != <localhost> # at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:220) # at org.apache.http.conn.ssl.BrowserCompatHostnameVerifier.verify(BrowserCompatHostnameVerifier.java:54)
B. 本文用到 httpcore-4.0.1.jar httpclient-4.0.1.jar httpmime-4.0.1.jar,下載地址:
http://hc.apache.org/downloads.cgi