Enabling specific SSL protocols with Android WebViewClient

后端 未结 4 2077
孤街浪徒
孤街浪徒 2020-11-30 02:17

My application uses WebViewClient to make SSL connections to the server. The server is configured to only accept TLSv1.1 and above protocols.

1) How do I check which

4条回答
  •  自闭症患者
    2020-11-30 02:54

    Actually, I managed to make it work, but you need okHttp library for that. Try this when you're setting up browser activity:

        WebViewClient client = new WebViewClient() {
            private OkHttpClient okHttp = new OkHttpClient.Builder().build();
    
            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
                Request okHttpRequest = new Request.Builder().url(url).build();
                try {
                    Response response = okHttp.newCall(okHttpRequest).execute();
                    return new WebResourceResponse(response.header("Content-Type", "plain/text"), response.header("Content-Encoding", "deflate"), response.body().byteStream());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }
        };
        webView.setWebViewClient(client);
    

    Also, you'll need classic Trust Manager Manipulator, SSL socket factory and its implementation in your Application class:

    public class TrustManagerManipulator implements X509TrustManager {
    
    
        private static TrustManager[] trustManagers;
        private static final X509Certificate[] acceptedIssuers = new X509Certificate[] {};
    
        public boolean isClientTrusted(X509Certificate[] chain) {
            return true;
        }
    
        public boolean isServerTrusted(X509Certificate[] chain) {
            return true;
        }
    
        public static void allowAllSSL()
        {
    
            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
            SSLContext context = null;
            if (trustManagers == null) {
                trustManagers = new TrustManager[] { new TrustManagerManipulator() };
            }
            try {
                context = SSLContext.getInstance("TLS");
                context.init(null, trustManagers, new SecureRandom());
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (KeyManagementException e) {
                e.printStackTrace();
            }
            HttpsURLConnection.setDefaultSSLSocketFactory(context
                    .getSocketFactory());
        }
    
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }
    
        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }
    
        public X509Certificate[] getAcceptedIssuers() {
            return acceptedIssuers;
        }
    }
    

    SSl Socket Factory:

    public class TLSSocketFactory extends SSLSocketFactory {
    
        private SSLSocketFactory internalSSLSocketFactory;
    
        public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
            SSLContext context = SSLContext.getInstance("TLS");
            TrustManager[] managers = new TrustManager[] { new TrustManagerManipulator() };
            context.init(null, managers, new SecureRandom());
            internalSSLSocketFactory = context.getSocketFactory();
        }
    
        @Override
        public String[] getDefaultCipherSuites() {
            return internalSSLSocketFactory.getDefaultCipherSuites();
        }
    
        @Override
        public String[] getSupportedCipherSuites() {
            return internalSSLSocketFactory.getSupportedCipherSuites();
        }
    
        @Override
        public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
            return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
        }
    
        @Override
        public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
            return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
        }
    
        @Override
        public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
            return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
        }
    
        @Override
        public Socket createSocket(InetAddress host, int port) throws IOException {
            return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
        }
    
        @Override
        public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
            return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
        }
    
        private Socket enableTLSOnSocket(Socket socket) {
            if(socket != null && (socket instanceof SSLSocket)) {
                ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
            }
            return socket;
        }
    }
    

    App class:

    public class App extends Application {
        private static App appInstance;
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            setupSSLconnections();
        }
    
        private void setupSSLconnections() {
            try {
                HttpsURLConnection.setDefaultSSLSocketFactory(new TLSSocketFactory());
            } catch (KeyManagementException | NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
        }
    }
    

提交回复
热议问题