HttpClient忽略用户证书验证的方法
程序中出了这样的异常:javax.net.ssl.SSLException: hostname in certificate didn‘t match。异常发生在这行代码上:httpClient.execute(httpGet);
初步判断是证书的问题,准备采用忽略证书的方法解决,但在网上找了半天都没找到靠谱的代码解决,最后还是自己琢磨解决了。
得到一个教训,网上找答案是不靠谱的,因为具体问题需要具体分析,别人的方法不一定能解决你的,一定要自己思考,自己琢磨。在网上最重要的是能找到问题的解决思路,最后还是要自己去思考解决自己问题的具体代码实现。
最后吐槽一句,网上的解决方法大多都是废话一箩筐,半天说不到核心解决方法上。
核心思路:继承SSLSocketFactory,重写一个验证证书时总是返回true的UnVerifySocketFactory,
* new一个这样的UnVerifySocketFactory对象设置到httpclient上就行了.代码如下:
import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.http.HttpVersion; import org.apache.http.client.HttpClient; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.conn.ssl.X509HostnameVerifier; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; import org.apache.http.protocol.HTTP; import android.util.Log; /** * 工具类:创建一个忽略用户证书验证的httpClient实例 * @date 2015-02-13 * @author Barry */ public class CertificateValidationIgnored { public static HttpClient getNoCertificateHttpClient(String url){ return getCertificateValidationIgnoredHttpClient(); } private static HttpClient getCertificateValidationIgnoredHttpClient() { try { KeyStore trustStore = KeyStore.getInstance(KeyStore .getDefaultType()); trustStore.load(null, null); //核心代码,创建一个UnVerifySocketFactory对象,验证证书时总是返回true SSLSocketFactory sf = new UnVerifySocketFactory(trustStore); HttpParams params = new BasicHttpParams(); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("http", PlainSocketFactory .getSocketFactory(), 80)); registry.register(new Scheme("https", sf, 443)); ClientConnectionManager ccm = new ThreadSafeClientConnManager( params, registry); return new DefaultHttpClient(ccm, params); } catch (Exception e) { Log.d("CertificateValidationIgnored", "创建忽略用户证书的HttpClient对象失败,尝试创建普通HttpClient对象"); e.printStackTrace(); return new DefaultHttpClient(); } } /** * 核心类 * UnVerifySocketFactory:一个验证证书时总是返回true的SSLSocketFactory的子类 */ private static X509HostnameVerifier ignoreVerifier; private static class UnVerifySocketFactory extends SSLSocketFactory { SSLContext sslContext = SSLContext.getInstance("TLS"); public UnVerifySocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { super(truststore); TrustManager tm = new X509TrustManager() { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return null; } }; sslContext.init(null, new TrustManager[] { tm }, null); } @Override public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); } //核心代码 @Override public void setHostnameVerifier(X509HostnameVerifier hostnameVerifier) { // TODO Auto-generated method stub ignoreVerifier = new X509HostnameVerifier() { @Override public void verify(String arg0, String[] arg1, String[] arg2) throws SSLException { } @Override public void verify(String arg0, X509Certificate arg1) throws SSLException { } @Override public void verify(String arg0, SSLSocket arg1) throws IOException { } //最最核心代码 @Override public boolean verify(String arg0, SSLSession arg1) { return true; } }; super.setHostnameVerifier(ignoreVerifier); } @Override public X509HostnameVerifier getHostnameVerifier() { return ignoreVerifier; } @Override public Socket createSocket() throws IOException { return sslContext.getSocketFactory().createSocket(); } } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。