0
点赞
收藏
分享

微信扫一扫

Android平台实现https信任所有证书…


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



1. schemeRegistry = new SchemeRegistry();  
2. schemeRegistry.register(new Scheme("https",  
3.                    new EasySSLSocketFactory(), 443));  
4. schemeRegistry.register(new Scheme("https",  
5.                    new EasySSLSocketFactory(), 8443));  
6. connManager = new ThreadSafeClientConnManager(params, schemeRegistry);  
7. httpClient = new DefaultHttpClient(connManager, params);



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



1. public class EasySSLSocketFactory implements SocketFactory,  
2.        LayeredSocketFactory {  
3.  
4.    private SSLContext sslcontext = null;  
5.  
6.    private static SSLContext createEasySSLContext() throws IOException {  
7.        try {  
8.            SSLContext context = SSLContext.getInstance("TLS");  
9.            context.init(null, new TrustManager[] { new EasyX509TrustManager(  
10.                    null) }, null);  
11.            return context;  
12.        } catch (Exception e) {  
13.            throw new IOException(e.getMessage());  
14.        }  
15.    }  
16.  
17.    private SSLContext getSSLContext() throws IOException {  
18.        if (this.sslcontext == null) {  
19.            this.sslcontext = createEasySSLContext();  
20.        }  
21.        return this.sslcontext;  
22.    }  
23.  
24.     
25.    public Socket connectSocket(Socket sock, String host, int port,  
26.            InetAddress localAddress, int localPort, HttpParams params)  
27.            throws IOException, UnknownHostException, ConnectTimeoutException {  
28.        int connTimeout = HttpConnectionParams.getConnectionTimeout(params);  
29.        int soTimeout = HttpConnectionParams.getSoTimeout(params);  
30.  
31.        InetSocketAddress remoteAddress = new InetSocketAddress(host, port);  
32.        SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket());  
33.  
34.        if ((localAddress != null) || (localPort > 0)) {  
35.            // we need to bind explicitly   
36.            if (localPort < 0) {  
37.                localPort = 0; // indicates "any"   
38.            }  
39.            InetSocketAddress isa = new InetSocketAddress(localAddress,  
40.                    localPort);  
41.            sslsock.bind(isa);  
42.        }  
43.  
44.        sslsock.connect(remoteAddress, connTimeout);  
45.        sslsock.setSoTimeout(soTimeout);  
46.        return sslsock;  
47.  
48.    }  
49.  
50.     
51.    public Socket createSocket() throws IOException {  
52.        return getSSLContext().getSocketFactory().createSocket();  
53.    }  
54.  
55.     
56.    public boolean isSecure(Socket socket) throws IllegalArgumentException {  
57.        return true;  
58.    }  
59.  
60.     
61.    public Socket createSocket(Socket socket, String host, int port,  
62.            boolean autoClose) throws IOException, UnknownHostException {  
63.        return getSSLContext().getSocketFactory().createSocket(socket, host,  
64.                port, autoClose);  
65.    }  
66.  
67.    // -------------------------------------------------------------------   
68.    // javadoc in org.apache.http.conn.scheme.SocketFactory says :   
69.    // Both Object.equals() and Object.hashCode() must be overridden   
70.    // for the correct operation of some connection managers   
71.    // -------------------------------------------------------------------   
72.  
73.    public boolean equals(Object obj) {  
74.        return ((obj != null) && obj.getClass().equals(  
75.                EasySSLSocketFactory.class));  
76.    }  
77.  
78.    public int hashCode() {  
79.        return EasySSLSocketFactory.class.hashCode();  
80.    }  
81. }  
82.  
83. public class EasyX509TrustManager implements X509TrustManager {  
84.  
85.    private X509TrustManager standardTrustManager = null;  
86.  
87.     
88.    public EasyX509TrustManager(KeyStore keystore)  
89.            throws NoSuchAlgorithmException, KeyStoreException {  
90.        super();  
91.        TrustManagerFactory factory = TrustManagerFactory  
92.               .getInstance(TrustManagerFactory.getDefaultAlgorithm());  
93.        factory.init(keystore);  
94.        TrustManager[] trustmanagers = factory.getTrustManagers();  
95.        if (trustmanagers.length == 0) {  
96.            throw new NoSuchAlgorithmException("no trust manager found");  
97.        }  
98.        this.standardTrustManager = (X509TrustManager) trustmanagers[0];  
99.    }  
100.  
101.     
102.    public void checkClientTrusted(X509Certificate[] certificates,  
103.            String authType) throws CertificateException {  
104.        standardTrustManager.checkClientTrusted(certificates, authType);  
105.    }  
106.  
107.     
108.    public void checkServerTrusted(X509Certificate[] certificates,  
109.            String authType) throws CertificateException {  
110.        if ((certificates != null) && (certificates.length == 1)) {  
111.            certificates[0].checkValidity();  
112.        } else {  
113.            standardTrustManager.checkServerTrusted(certificates, authType);  
114.        }  
115.    }  
116.  
117.     
118.    public X509Certificate[] getAcceptedIssuers() {  
119.        return this.standardTrustManager.getAcceptedIssuers();  
120.    }  
121. }

举报

相关推荐

0 条评论