美文网首页
Android Https单向验证

Android Https单向验证

作者: 耳_总 | 来源:发表于2017-05-16 09:34 被阅读533次

    最近在维护一个老掉牙的项目,用了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就行了

    相关文章

      网友评论

          本文标题:Android Https单向验证

          本文链接:https://www.haomeiwen.com/subject/dwuwnttx.html