文档章节

Android平台实现https信任所有证书的方法

火云
 火云
发布于 2015/06/04 10:27
字数 662
阅读 28
收藏 0

Android平台上经常有使用https的需求,对于https服务器使用的根证书是受信任的证书的话,实现https是非常简单的,直接用httpclient库就行了,与使用http几乎没有区别。但是在大多数情况下,服务器所使用的根证书是自签名的,或者签名机构不在设备的信任证书列表中,这样使用httpclient进行https连接就会失败。解决这个问题的办法有两种,一是在发起https连接之前将服务器证书加到httpclient的信任证书列表中,这个相对来说比较复杂一些,很容易出错;另一种办法是让httpclient信任所有的服务器证书,这种办法相对来说简单很多,但安全性则差一些,但在某些场合下有一定的应用场景。这里要举例说明的就是后一种方法:实例化HttpClinet对象时要进行一些处理主要是绑定https连接所使用的端口号,这里绑定了443和8443:

  1. SchemeRegistry schemeRegistry = new SchemeRegistry();  
    schemeRegistry.register(new Scheme("https",  
                        new EasySSLSocketFactory(), 443));  
    schemeRegistry.register(new Scheme("https",  
                        new EasySSLSocketFactory(), 8443));  
    ClientConnectionManager connManager = new ThreadSafeClientConnManager(params, schemeRegistry);  
    HttpClient httpClient = new DefaultHttpClient(connManager, params);



上面的EasySSLSocketFactory类是我们自定义的,主要目的就是让httpclient接受所有的服务器证书,能够正常的进行https数据读取。相关代码如下:

  1. public class EasySSLSocketFactory implements SocketFactory,  
            LayeredSocketFactory {  
      
        private SSLContext sslcontext = null;  
      
        private static SSLContext createEasySSLContext() throws IOException {  
            try {  
                SSLContext context = SSLContext.getInstance("TLS");  
                context.init(null, new TrustManager[] { new EasyX509TrustManager(  
                        null) }, null);  
                return context;  
            } catch (Exception e) {  
                throw new IOException(e.getMessage());  
            }  
        }  
      
        private SSLContext getSSLContext() throws IOException {  
            if (this.sslcontext == null) {  
                this.sslcontext = createEasySSLContext();  
            }  
            return this.sslcontext;  
        }  
      
         
        public Socket connectSocket(Socket sock, String host, int port,  
                InetAddress localAddress, int localPort, HttpParams params)  
                throws IOException, UnknownHostException, ConnectTimeoutException {  
            int connTimeout = HttpConnectionParams.getConnectionTimeout(params);  
            int soTimeout = HttpConnectionParams.getSoTimeout(params);  
      
            InetSocketAddress remoteAddress = new InetSocketAddress(host, port);  
            SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket());  
      
            if ((localAddress != null) || (localPort > 0)) {  
                // we need to bind explicitly  
                if (localPort < 0) {  
                    localPort = 0; // indicates "any"  
                }  
                InetSocketAddress isa = new InetSocketAddress(localAddress,  
                        localPort);  
                sslsock.bind(isa);  
            }  
      
            sslsock.connect(remoteAddress, connTimeout);  
            sslsock.setSoTimeout(soTimeout);  
            return sslsock;  
      
        }  
      
         
        public Socket createSocket() throws IOException {  
            return getSSLContext().getSocketFactory().createSocket();  
        }  
      
         
        public boolean isSecure(Socket socket) throws IllegalArgumentException {  
            return true;  
        }  
      
         
        public Socket createSocket(Socket socket, String host, int port,  
                boolean autoClose) throws IOException, UnknownHostException {  
            return getSSLContext().getSocketFactory().createSocket(socket, host,  
                    port, autoClose);  
        }  
      
        // -------------------------------------------------------------------  
        // javadoc in org.apache.http.conn.scheme.SocketFactory says :  
        // Both Object.equals() and Object.hashCode() must be overridden  
        // for the correct operation of some connection managers  
        // -------------------------------------------------------------------  
      
        public boolean equals(Object obj) {  
            return ((obj != null) && obj.getClass().equals(  
                    EasySSLSocketFactory.class));  
        }  
      
        public int hashCode() {  
            return EasySSLSocketFactory.class.hashCode();  
        }  
    }  
      
    public class EasyX509TrustManager implements X509TrustManager {  
      
        private X509TrustManager standardTrustManager = null;  
      
         
        public EasyX509TrustManager(KeyStore keystore)  
                throws NoSuchAlgorithmException, KeyStoreException {  
            super();  
            TrustManagerFactory factory = TrustManagerFactory  
                   .getInstance(TrustManagerFactory.getDefaultAlgorithm());  
            factory.init(keystore);  
            TrustManager[] trustmanagers = factory.getTrustManagers();  
            if (trustmanagers.length == 0) {  
                throw new NoSuchAlgorithmException("no trust manager found");  
            }  
            this.standardTrustManager = (X509TrustManager) trustmanagers[0];  
        }  
      
         
        public void checkClientTrusted(X509Certificate[] certificates,  
                String authType) throws CertificateException {  
            standardTrustManager.checkClientTrusted(certificates, authType);  
        }  
      
         
        public void checkServerTrusted(X509Certificate[] certificates,  
                String authType) throws CertificateException {  
            if ((certificates != null) && (certificates.length == 1)) {  
                certificates[0].checkValidity();  
            } else {  
                standardTrustManager.checkServerTrusted(certificates, authType);  
            }  
        }  
      
         
        public X509Certificate[] getAcceptedIssuers() {  
            return this.standardTrustManager.getAcceptedIssuers();  
        }  
    }


本文转载自:http://blog.csdn.net/123bobo/article/details/7264350/

火云
粉丝 4
博文 94
码字总数 11969
作品 0
西城
Android工程师
私信 提问
Android端支持HTTP和HTTPS

作者:近乎团队 Android端的网络模块在程序开发中是至关重要的,今天我们来分享下Android端如何使用http和https 技术。 1 HTTP (Hypertext transfer protocol) 超文本传输 协议 是一个基于请...

小近
2014/10/22
15.1K
4
你的Android HTTPS真的安全吗?

随着数据量级和维度的不断增加,数据安全已经成为移动互联网行业重点关注的领域。尤其是数据传输过程,是相对比较容易被拦截和嗅探的,因此谷歌对数据传输安全提出了更高的要求,推动Android...

TalkingData
2016/09/26
397
0
聊聊 Android HTTPS 的使用姿势

HTTPS 简介 HTTPS 全称 HTTP over TLS。TLS是在传输层上层的协议,应用层的下层,作为一个安全层而存在,翻译过来一般叫做传输层安全协议。 对 HTTP 而言,安全传输层是透明不可见的,应用层...

任我行
2017/03/17
0
0
Android 7.0 以上 Charles 和 Fiddler 无法抓取 HTTPS 包的解决方式

最近升级了 targetSdkVersion 到 28 后发现在 Android 7.0 以上机型 Charles 抓取 https 包时显示找不到证书,但是 Android 6.0 机型还是可以正常抓包。原因是因为从 Android 7.0 开始,默认...

JohnnyShieh
05/06
0
0
浅入浅出 Android 安全:第六章 Android 安全的其它话题

第六章 Android 安全的其它话题 来源:Yury Zhauniarovich | Publications 译者:飞龙 协议:CC BY-NC-SA 4.0 在本章中,我们会涉及到与 Android 安全相关的其他主题,这些主题不直接属于已经...

apachecn_飞龙
2016/12/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

texlive安装

Installing to: D:/bin/texlive/texlive/2019Installing [001/307, time/total: ??:??/??:??]: adobemapping [2130k]Installing [002/307, time/total: 00:03/08:57]: ae [84k]Installing......

MtrS
今天
2
0
运维规范

命名规范 发布流程 监控告警 故障定位 状态 日志 监控

以谁为师
今天
2
0
约瑟夫环(报数游戏)java实现

开端 公司组织考试,一拿到考题,就是算法里说的约瑟夫环,仔细想想 以前老师将的都忘了,还是自己琢磨把~ package basic.gzy;import java.util.Iterator;import java.util.LinkedList;...

无极之岚
今天
3
0
Kernel字符设备驱动框架

Linux设备分为三大类:字符设备,块设备和网络设备,这三种设备基于不同的设备框架。相较于块设备和网络设备,字符设备在kernel中是最简单的,也是唯一没有基于设备基础框架(device结构)的...

yepanl
今天
3
0
Jenkins 中文本地化的重大进展

本文首发于:Jenkins 中文社区 我从2017年开始,参与 Jenkins 社区贡献。作为一名新成员,翻译可能是帮助社区项目最简单的方法。 本地化的优化通常是较小的改动,你无需了解项目完整的上下文...

Jenkins中文社区
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部