Android Https单向验证

最近在维护一个老掉牙的项目,用了HttpClient,而且还要改用Https协议,于是客户端报错了:javax.net.ssl.SSLPeerUnverifiedException: No peer certificate ,这是使用https没有验证证书导致,解决的方式有两种:
单向验证和双向验证,单向验证信任所有的证书,有安全风险,双向验证是建立在单向验证的基础上的,然后做了个单向验证:

/**
     * https 单向ssl认证
     * @return
     */
    public static HttpClient getNewHttpsClient() {  
        try {  
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());  
            trustStore.load(null, null);  
            
            SSLSocketFactoryEx sf = new SSLSocketFactoryEx(trustStore);
            sf.setHostnameVerifier(SSLSocketFactoryEx.ALLOW_ALL_HOSTNAME_VERIFIER);  
    
            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));  
            registry.register(new Scheme("https", sf, 8443));
    
            ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);  
    
            return new DefaultHttpClient(ccm, params);  
        } catch (Exception e) {  
            return new DefaultHttpClient();  
        }  
    }  
    
    public static 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();  
        }  
    } 

    public static class SSLSocketFactoryEx extends SSLSocketFactory {

        SSLContext sslContext = SSLContext.getInstance("TLS");

        public SSLSocketFactoryEx(KeyStore truststore) throws
                NoSuchAlgorithmException, KeyManagementException,
                KeyStoreException, UnrecoverableKeyException {
            
            super(truststore);

            
            sslContext.init(null, new TrustManager[] { new EasyX509TrustManager(  
                    null) }, 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 Socket createSocket() throws IOException {
            return sslContext.getSocketFactory().createSocket();
        }
        
        private SSLContext getSSLContext() throws IOException {  
            return this.sslContext;  
        }  
        
        @Override
        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 boolean isSecure(Socket socket) throws IllegalArgumentException {  
            return true;  
        }  
      
        // -------------------------------------------------------------------  
        // 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(  
                    SSLSocketFactoryEx.class));  
        }  
      
        public int hashCode() {  
            return SSLSocketFactoryEx.class.hashCode();  
        }  
    }

在使用的时候调用getNewHttpsClient()替换原来的httpClient就行了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容