天天看點

Android SSL 認證

Android 6.0之前SSL認證

/**
 * 
 */

import java.io.InputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import org.apache.http.conn.ssl.SSLSocketFactory;
import android.content.Context;

public class HttpClientSslHelper {
	private static final String TAG = "HttpClientSslHelper";

	private static final String KEY_STORE_TYPE_P12 = "PKCS12";
	private static final String KEY_STORE_CLIENT_PATH = "client.p12";
	private static final String SERVER_CRT_PATH = "server.crt";
	private static final String KEY_STORE_PASSWORD = "[email protected]";

	private static KeyStore keyStore;

	private static KeyStore trustStore;

	@SuppressWarnings("deprecation")
	public static SSLSocketFactory getSslHttpClient(Context pContext) {
		try {
			// 伺服器端需要驗證的用戶端證書
			keyStore = KeyStore.getInstance(KEY_STORE_TYPE_P12);
			// 用戶端信任的伺服器端證書
			trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
			InputStream ksIn = pContext.getResources().getAssets().open(KEY_STORE_CLIENT_PATH);
			InputStream tsIn = pContext.getResources().getAssets().open(SERVER_CRT_PATH);

			/**
			 * for Self-signed server certificate
			 * 
			 * @see{@link http://developer.android.com/intl/zh-cn/training/
			 *            articles/security-ssl.html }
			 */
			CertificateFactory cf = CertificateFactory.getInstance("X.509");
			Certificate ca = null;

			try {
				keyStore.load(ksIn, KEY_STORE_PASSWORD.toCharArray());

				/**
				 * Self-signed server certificate
				 */
				trustStore.load(null, null);
				ca = cf.generateCertificate(tsIn);
				trustStore.setCertificateEntry("ca", ca);

			} catch (Exception e) {
				LogUtil.e("SSLSocketFactory", e.getMessage());
			} finally {
				try {
					tsIn.close();
					ksIn.close();
				} catch (Exception ignore) {
				}
			}
			SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore, KEY_STORE_PASSWORD, trustStore);
			return socketFactory;
		} catch (Exception e) {
			LogUtil.e("SSLSocketFactory", e.getMessage());
		}
		return null;
	}
	
	
}
           
public HttpUtils(int connTimeout, String userAgent) {
        HttpParams params = new BasicHttpParams();

        ConnManagerParams.setTimeout(params, connTimeout);
        HttpConnectionParams.setSoTimeout(params, connTimeout);
        HttpConnectionParams.setConnectionTimeout(params, connTimeout);

        if (TextUtils.isEmpty(userAgent)) {
            userAgent = OtherUtils.getUserAgent(null);
        }
        HttpProtocolParams.setUserAgent(params, userAgent);

        ConnManagerParams.setMaxConnectionsPerRoute(params, new ConnPerRouteBean(10));
        ConnManagerParams.setMaxTotalConnections(params, 10);

        HttpConnectionParams.setTcpNoDelay(params, true);
        HttpConnectionParams.setSocketBufferSize(params, 1024 * 8);
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);

        SchemeRegistry schemeRegistry = new SchemeRegistry();
        schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        schemeRegistry.register(new Scheme("https", DefaultSSLSocketFactory.getSocketFactory(), 443));

        httpClient = new DefaultHttpClient(new ThreadSafeClientConnManager(params, schemeRegistry), params);

        httpClient.setHttpRequestRetryHandler(new RetryHandler(DEFAULT_RETRY_TIMES));

        httpClient.addRequestInterceptor(new HttpRequestInterceptor() {
            @Override
            public void process(org.apache.http.HttpRequest httpRequest, HttpContext httpContext) throws org.apache.http.HttpException, IOException {
                if (!httpRequest.containsHeader(HEADER_ACCEPT_ENCODING)) {
                    httpRequest.addHeader(HEADER_ACCEPT_ENCODING, ENCODING_GZIP);
                }
            }
        });

        httpClient.addResponseInterceptor(new HttpResponseInterceptor() {
            @Override
            public void process(HttpResponse response, HttpContext httpContext) throws org.apache.http.HttpException, IOException {
                final HttpEntity entity = response.getEntity();
                if (entity == null) {
                    return;
                }
                final Header encoding = entity.getContentEncoding();
                if (encoding != null) {
                    for (HeaderElement element : encoding.getElements()) {
                        if (element.getName().equalsIgnoreCase("gzip")) {
                            response.setEntity(new GZipDecompressingEntity(response.getEntity()));
                            return;
                        }
                    }
                }
            }
        });
    }
           
public HttpUtils configSSLSocketFactory(SSLSocketFactory sslSocketFactory) {
        Scheme scheme = new Scheme("https", sslSocketFactory, 443);
        this.httpClient.getConnectionManager().getSchemeRegistry().register(scheme);
        return this;
    }
           

Android 6.0之後

public static SSLSocketFactory getFactory(){
		return getSSLSocketFactory(KEY_STORE_PASSWORD,KEY_STORE_CLIENT_PATH,SERVER_CRT_PATH);
	}
	/**
	 * 獲得SSLSocektFactory
	 * 
	 * @param password
	 *            密碼
	 * @param keyStorePath
	 *            密鑰庫路徑
	 * 
	 * @param trustKeyStorePath
	 *            信任庫路徑
	 * @return
	 * @throws Exception
	 */
	private static SSLSocketFactory getSSLSocketFactory(String password,
			String keyStorePath, String trustKeyStorePath){
		// 初始化密鑰庫
		KeyManagerFactory keyManagerFactory;
		try {
			keyManagerFactory = KeyManagerFactory
					.getInstance(TrustManagerFactory.getDefaultAlgorithm());
		KeyStore keyStore = getKeyStore(keyStorePath, password);
		keyManagerFactory.init(keyStore, password.toCharArray());

		// 初始化信任庫
		TrustManagerFactory trustManagerFactory = TrustManagerFactory
				.getInstance(TrustManagerFactory.getDefaultAlgorithm());
				
				
		CertificateFactory cf = CertificateFactory.getInstance("X.509");
		Certificate ca = null;
		InputStream tsIn = CommonApplication.getApplication().getResources().getAssets().open(trustKeyStorePath);
		KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
		trustStore.load(null, null);
		ca = cf.generateCertificate(tsIn);
		trustStore.setCertificateEntry("ca", ca);
		trustManagerFactory.init(trustStore);

		// 初始化SSL上下文
		SSLContext ctx = SSLContext.getInstance(SSL);
		ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory
				.getTrustManagers(), null);
		SSLSocketFactory sf = ctx.getSocketFactory();
		return sf;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return getTrustAllSSLSocketFactory();
	}
	/**
	 * 獲得KeyStore
	 * 
	 * @param keyStorePath
	 * @param password
	 * @return
	 * @throws Exception
	 */
	private static KeyStore getKeyStore(String keyStorePath, String password)
			throws Exception {
		InputStream is = CommonApplication.getApplication().getResources().getAssets().open(keyStorePath);
		KeyStore ks = KeyStore.getInstance(KEY_STORE_TYPE_P12);
		ks.load(is, password.toCharArray());
		is.close();
		return ks;
	}
	public static final String SSL = "SSL";
	private static final String KEY_STORE_TYPE_P12 = "PKCS12";
	private static final String KEY_STORE_CLIENT_PATH = "client.p12";
	private static final String SERVER_CRT_PATH = "server.crt";
	private static final String KEY_STORE_PASSWORD = "password";
           
<pre name="code" class="java">HttpURLConnection  connection = (HttpURLConnection) url.openConnection();
            }

            // try to fix bug: accidental EOFException before API 19
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
                connection.setRequestProperty("Connection", "close");
            }


            connection.setReadTimeout(params.getConnectTimeout());
            connection.setConnectTimeout(params.getConnectTimeout());
            connection.setInstanceFollowRedirects(params.getRedirectHandler() == null);
            if (connection instanceof HttpsURLConnection) {
                SSLSocketFactory sslSocketFactory = params.getSslSocketFactory();
                if (sslSocketFactory != null) {
                    ((HttpsURLConnection) connection).setSSLSocketFactory(sslSocketFactory);
                }
            }