Android ignore https certificate verification

简介:

通过Https访问的时候经常会遇到"Not trusted Server Certificate"的问题,有人说在3.0上面没有这个问题,可能已经改进了,在2.2及以前的版本中有这个问题。

开始想的是采用安装证书的方法(Trusting SSL certificates),最后也没有成功,不知道是证书的原因还是其他,有人说安装证书只能在WIFI上使用,没有找到官方文档,用户可能在GPRS上使用,只能放弃。

StackOverflow上也有相关的方案,我整理了一下。

我将注册的步骤封装到DefaultHttpClient子类中了,这样看上去更清晰一些,你也可以

直接实例化DefaultHttpClient的方法。

 
 
  1. SchemeRegistry schemeRegistry = new SchemeRegistry(); schemeRegistry.register(new Scheme ("https", sslf, 443));  
  2. SingleClientConnManager cm = new  
  3. SingleClientConnManager(post.getParams(), schemeRegistry);  
  4. HttpClient client = new DefaultHttpClient(cm, post.getParams()); 
 
 
  1. /** 
  2.  * @author Brant 
  3.  * @decription 
  4.  */ 
  5. public class SSLHttpClient extends DefaultHttpClient { 
  6.  
  7.     @Override 
  8.     protected ClientConnectionManager createClientConnectionManager() { 
  9.         SchemeRegistry registry = new SchemeRegistry(); 
  10.         registry.register(new Scheme("http", PlainSocketFactory 
  11.                 .getSocketFactory(), 80)); 
    //443是Https的默认端口,如果网站配置的端口不一样,这里要记着改一下
  12.         registry.register(new Scheme("https"new EasySSLSocketFactory(), 443)); 
  13.         return new SingleClientConnManager(getParams(), registry); 
  14.  
  15.     } 
  16.  
  17.     public static SSLHttpClient getInstance() { 
  18.         SSLHttpClient client = new SSLHttpClient(); 
  19.         client.setCookieStore(mCookie); 
  20.         return client; 
  21.     } 

 EasySSLSocketFactory:

 
 
  1. import java.io.IOException; 
  2. import java.net.InetAddress; 
  3. import java.net.InetSocketAddress; 
  4. import java.net.Socket; 
  5. import java.net.UnknownHostException; 
  6.  
  7. import javax.net.ssl.SSLContext; 
  8. import javax.net.ssl.SSLSocket; 
  9. import javax.net.ssl.TrustManager; 
  10.  
  11. import org.apache.http.conn.ConnectTimeoutException; 
  12. import org.apache.http.conn.scheme.LayeredSocketFactory; 
  13. import org.apache.http.conn.scheme.SocketFactory; 
  14. import org.apache.http.params.HttpConnectionParams; 
  15. import org.apache.http.params.HttpParams; 
  16.  
  17. /** 
  18.  * This socket factory will create ssl socket that accepts self signed 
  19.  * certificate 
  20.  *  
  21.  * @author olamy 
  22.  * @version $Id: EasySSLSocketFactory.java 765355 2009-04-15 20:59:07Z evenisse 
  23.  *          $ 
  24.  * @since 1.2.3 
  25.  */ 
  26. public class EasySSLSocketFactory implements SocketFactory, 
  27.         LayeredSocketFactory { 
  28.  
  29.     private SSLContext sslcontext = null
  30.  
  31.     private static SSLContext createEasySSLContext() throws IOException { 
  32.         try { 
  33.             SSLContext context = SSLContext.getInstance("TLS"); 
  34.             context.init(nullnew TrustManager[] { new EasyX509TrustManager( 
  35.                     null) }, null); 
  36.             return context; 
  37.         } catch (Exception e) { 
  38.             throw new IOException(e.getMessage()); 
  39.         } 
  40.     } 
  41.  
  42.     private SSLContext getSSLContext() throws IOException { 
  43.         if (this.sslcontext == null) { 
  44.             this.sslcontext = createEasySSLContext(); 
  45.         } 
  46.         return this.sslcontext; 
  47.     } 
  48.  
  49.     /** 
  50.      * @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket, 
  51.      *      java.lang.String, int, java.net.InetAddress, int, 
  52.      *      org.apache.http.params.HttpParams) 
  53.      */ 
  54.     public Socket connectSocket(Socket sock, String host, int port, 
  55.             InetAddress localAddress, int localPort, HttpParams params) 
  56.             throws IOException, UnknownHostException, ConnectTimeoutException { 
  57.         int connTimeout = HttpConnectionParams.getConnectionTimeout(params); 
  58.         int soTimeout = HttpConnectionParams.getSoTimeout(params); 
  59.  
  60.         InetSocketAddress remoteAddress = new InetSocketAddress(host, port); 
  61.         SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket()); 
  62.  
  63.         if ((localAddress != null) || (localPort > 0)) { 
  64.             // we need to bind explicitly 
  65.             if (localPort < 0) { 
  66.                 localPort = 0// indicates "any" 
  67.             } 
  68.             InetSocketAddress isa = new InetSocketAddress(localAddress, 
  69.                     localPort); 
  70.             sslsock.bind(isa); 
  71.         } 
  72.  
  73.         sslsock.connect(remoteAddress, connTimeout); 
  74.         sslsock.setSoTimeout(soTimeout); 
  75.         return sslsock; 
  76.  
  77.     } 
  78.  
  79.     /** 
  80.      * @see org.apache.http.conn.scheme.SocketFactory#createSocket() 
  81.      */ 
  82.     public Socket createSocket() throws IOException { 
  83.         return getSSLContext().getSocketFactory().createSocket(); 
  84.     } 
  85.  
  86.     /** 
  87.      * @see org.apache.http.conn.scheme.SocketFactory#isSecure(java.net.Socket) 
  88.      */ 
  89.     public boolean isSecure(Socket socket) throws IllegalArgumentException { 
  90.         return true;//不判断socket,直接返回true
  91.     } 
  92.  
  93.     /** 
  94.      * @see org.apache.http.conn.scheme.LayeredSocketFactory#createSocket(java.net.Socket, 
  95.      *      java.lang.String, int, boolean) 
  96.      */ 
  97.     public Socket createSocket(Socket socket, String host, int port, 
  98.             boolean autoClose) throws IOException, UnknownHostException { 
  99. //return getSSLContext().getSocketFactory().createSocket();
  100. //will get java.io.IOException: SSL handshake failure: I/O error
  101. //during system call, Broken pipe 
  102.         return getSSLContext().getSocketFactory().createSocket(socket, host, 
  103.                 port, autoClose); 
  104.     } 
  105.  
  106.     // ------------------------------------------------------------------- 
  107.     // javadoc in org.apache.http.conn.scheme.SocketFactory says : 
  108.     // Both Object.equals() and Object.hashCode() must be overridden 
  109.     // for the correct operation of some connection managers 
  110.     // ------------------------------------------------------------------- 
  111.  
  112.     public boolean equals(Object obj) { 
  113.         return ((obj != null) && obj.getClass().equals( 
  114.                 EasySSLSocketFactory.class)); 
  115.     } 
  116.  
  117.     public int hashCode() { 
  118.         return EasySSLSocketFactory.class.hashCode(); 
  119.     } 
  120.  

EasyX509TrustManager:

 
 
  1. import java.security.KeyStore; 
  2. import java.security.KeyStoreException; 
  3. import java.security.NoSuchAlgorithmException; 
  4. import java.security.cert.CertificateException; 
  5. import java.security.cert.X509Certificate; 
  6.  
  7. import javax.net.ssl.TrustManager; 
  8. import javax.net.ssl.TrustManagerFactory; 
  9. import javax.net.ssl.X509TrustManager; 
  10.  
  11. /** 
  12.  * @author olamy 
  13.  * @version $Id: EasyX509TrustManager.java 765355 2009-04-15 20:59:07Z evenisse 
  14.  *          $ 
  15.  * @since 1.2.3 
  16.  */ 
  17. public class EasyX509TrustManager implements X509TrustManager { 
  18.  
  19.     private X509TrustManager standardTrustManager = null
  20.  
  21.     /** 
  22.      * Constructor for EasyX509TrustManager. 
  23.      */ 
  24.     public EasyX509TrustManager(KeyStore keystore) 
  25.             throws NoSuchAlgorithmException, KeyStoreException { 
  26.         super(); 
  27.         TrustManagerFactory factory = TrustManagerFactory 
  28.                 .getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
  29.         factory.init(keystore); 
  30.         TrustManager[] trustmanagers = factory.getTrustManagers(); 
  31.         if (trustmanagers.length == 0) { 
  32.             throw new NoSuchAlgorithmException("no trust manager found"); 
  33.         } 
  34.         this.standardTrustManager = (X509TrustManager) trustmanagers[0]; 
  35.     } 
  36.  
  37.     /** 
  38.      * @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[], 
  39.      *      String authType) 
  40.      */ 
  41.     public void checkClientTrusted(X509Certificate[] certificates, 
  42.             String authType) throws CertificateException { 
  43.         standardTrustManager.checkClientTrusted(certificates, authType); 
  44.     } 
  45.  
  46.     /** 
  47.      * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[], 
  48.      *      String authType) 
  49.      */ 
  50.     public void checkServerTrusted(X509Certificate[] certificates, 
  51.             String authType) throws CertificateException { 
  52.         if ((certificates != null) && (certificates.length == 1)) { 
  53.             certificates[0].checkValidity(); 
  54.         } else { 
  55.             standardTrustManager.checkServerTrusted(certificates, authType); 
  56.         } 
  57.     } 
  58.  
  59.     /** 
  60.      * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers() 
  61.      */ 
  62.     public X509Certificate[] getAcceptedIssuers() { 
  63.         return this.standardTrustManager.getAcceptedIssuers(); 
  64.     } 
  65.  

然后直接实例化SSLHttpClient就可以想Http一样执行HttpGet和HttpPost方法了,希望能有所帮助:)。










本文转自 breezy_yuan 51CTO博客,原文链接:http://blog.51cto.com/lbrant/795636,如需转载请自行联系原作者
目录
相关文章
|
15天前
|
安全 搜索推荐 Android开发
Android安全性: 解释HTTPS在移动应用中的重要性。
Android安全性: 解释HTTPS在移动应用中的重要性。
26 0
|
6月前
|
安全 Android开发
夜神模拟器 安卓7.0 burp抓包 https流量
夜神模拟器 安卓7.0 burp抓包 https流量
203 0
|
8月前
|
网络协议 算法 安全
Android 面试必备 - 计算机网络基本知识(TCP,UDP,Http,https)
Android 面试必备 - 计算机网络基本知识(TCP,UDP,Http,https)
|
14天前
|
安全 Android开发
Android之OKHttp基本使用和OKHttp发送https请求安全认证
Android之OKHttp基本使用和OKHttp发送https请求安全认证
50 0
|
15天前
|
Android开发
Android中Glide加载Https图片失败的解决方案
Android中Glide加载Https图片失败的解决方案
21 1
|
15天前
|
网络协议 安全 API
Android网络和数据交互: 什么是HTTP和HTTPS?在Android中如何进行网络请求?
HTTP和HTTPS是网络数据传输协议,HTTP基于TCP/IP,简单快速,HTTPS则是加密的HTTP,确保数据安全。在Android中,过去常用HttpURLConnection和HttpClient,但HttpClient自Android 6.0起被移除。现在推荐使用支持TLS、流式上传下载、超时配置等特性的HttpsURLConnection进行网络请求。
16 0
|
15天前
|
Web App开发 前端开发 网络安全
前端分析工具之 Charles 录制 Android/IOS 手机的 https 应用
【2月更文挑战第21天】前端分析工具之 Charles 录制 Android/IOS 手机的 https 应用
62 1
前端分析工具之 Charles 录制 Android/IOS 手机的 https 应用
|
7月前
|
JavaScript 安全 应用服务中间件
Node.js 应用访问 https 服务器时遇到的错误消息 unable to get local issuer certificate
Node.js 应用访问 https 服务器时遇到的错误消息 unable to get local issuer certificate
85 1
|
11月前
|
前端开发 API 定位技术
Android webview加载https链接错误或无响应
Android webview加载https链接错误或无响应
|
11月前
|
JSON Java Android开发
让android支持https访问银联后台,测试成功
让android支持https访问银联后台,测试成功