android访问自签CA的Https SSL双向认证(j2SE也能使用)
主要的核心代码是HttpsClient.java
其实思路就是客户端证书要验证,CA证书就跳过认证
package com.bron.test.mobiletestssl.util;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.Reader;import java.net.URL;import java.security.GeneralSecurityException;import java.security.KeyStore;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;import javax.net.ssl.HostnameVerifier;import javax.net.ssl.HttpsURLConnection;import javax.net.ssl.KeyManagerFactory;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLSession;import javax.net.ssl.SSLSocketFactory;import javax.net.ssl.TrustManager;import javax.net.ssl.X509TrustManager;import android.util.Log;/** * The summery of the class. * <ul> * <li>File name : HttpsClient.java</li> * <li>Description : The detail description of the class</li> * <li>Copyright : Copyright(C)2008-2014</li> * <li>Company : CST</li> * <li>remark :</li> * <li>create date : 2014-1-7</li> * </ul> * * @version 1.0 * @author 许力多 */public class HttpsClient {private final static String TAG = "HttpsClient";public StringBuilder ssl(URL url, InputStream keyInput, String pKeyPassword) {StringBuilder response = new StringBuilder();HttpsURLConnection conn = null;BufferedReader br = null;Reader reader = null;try {conn = (HttpsURLConnection) url.openConnection();// 设置ssl工厂conn.setSSLSocketFactory(getFactory(keyInput, pKeyPassword));// 忽略主机名验证conn.setHostnameVerifier(new HostnameVerifier() {@Overridepublic boolean verify(String arg0, SSLSession arg1) {return true;}});// System.out.println(conn.getResponseCode());// 读取结果,这个效率不太高,只是demo使用reader = new InputStreamReader(conn.getInputStream());br = new BufferedReader(reader);String line = "";while ((line = br.readLine()) != null) {response.append(line);response.append('\n');}} catch (IOException e) {response.append(e.getLocalizedMessage());Log.e(TAG, e.getLocalizedMessage(), e);} catch (GeneralSecurityException e) {response.append(e.getLocalizedMessage());Log.e(TAG, e.getLocalizedMessage(), e);} finally {try {br.close();} catch (Exception e) {}conn.disconnect();}return response;}/** * 获得ssl连接的验证工厂 * * @param keyInput * @param pKeyPassword * @return * @throws GeneralSecurityException * @throws IOException */private SSLSocketFactory getFactory(InputStream keyInput,String pKeyPassword) throws GeneralSecurityException, IOException {// j2se要使用SUNX509KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("X509");// 使用p12格式的证书,也支持其他类型的,具体请看KeyStore的APIKeyStore keyStore = KeyStore.getInstance("PKCS12");// InputStream keyInput = new FileInputStream(pKeyFile);keyStore.load(keyInput, pKeyPassword.toCharArray());keyInput.close();keyManagerFactory.init(keyStore, pKeyPassword.toCharArray());SSLContext context = SSLContext.getInstance("TLS");// init的第一个参数是验证客户端证书,第二个参数验证CA证书,由于私签的CA,所有绕过证书安全认证context.init(keyManagerFactory.getKeyManagers(),new TrustManager[] { new DefaultTrustManager() }, null);if (keyInput != null) {keyInput.close();}return context.getSocketFactory();}/** * * The summery of the class. * <ul> * <li>File name : HttpsClient.java</li> * <li>Description :绕过证书(信任证书)的验证</li> * <li>Copyright : Copyright(C)2008-2014</li> * <li>Company : CST</li> * <li>remark :</li> * <li>create date : 2014-1-8</li> * </ul> * * @version 1.0 * @author 许力多 */class DefaultTrustManager implements X509TrustManager {@Overridepublic void checkClientTrusted(X509Certificate[] arg0, String arg1)throws CertificateException {}@Overridepublic void checkServerTrusted(X509Certificate[] arg0, String arg1)throws CertificateException {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return null;}}}