Android Https單向驗證

最近在維護一個老掉牙的項目,用了HttpClient,而且還要改用Https協(xié)議,于是客戶端報錯了:javax.net.ssl.SSLPeerUnverifiedException: No peer certificate ,這是使用https沒有驗證證書導(dǎo)致,解決的方式有兩種:
單向驗證和雙向驗證,單向驗證信任所有的證書,有安全風(fēng)險,雙向驗證是建立在單向驗證的基礎(chǔ)上的,然后做了個單向驗證:

/**
     * https 單向ssl認(rèn)證
     * @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();  
        }  
    }

在使用的時候調(diào)用getNewHttpsClient()替換原來的httpClient就行了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容