首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Android WebViewClient启用特定的SSL协议

使用Android WebViewClient启用特定的SSL协议
EN

Stack Overflow用户
提问于 2015-02-04 19:22:23
回答 4查看 20.6K关注 0票数 27

我的应用程序使用WebViewClient与服务器建立SSL连接。服务器配置为只接受TLSv1.1及以上协议。

  1. 当在设备上使用Android WebViewClient时,如何检查哪些SSL协议是( a)支持的( b)默认启用的。
  2. 如何为我的应用程序中使用的Android WebViewClient实例启用特定的SSL协议。

在运行Android4.3的一个测试设备上,WebViewClient抛出带有以下描述的onReceivedError回调:

“未能执行SSL握手”

Chrome日志如下:

代码语言:javascript
复制
01-29 15:58:00.073 5486 5525 W chromium_net: external/chromium/net/http/http_stream_factory_impl_job.cc:865: [0129/155800:WARNING:http_stream_factory_impl_job.cc(865)] Falling back to SSLv3 because host is TLS intolerant: 10.209.126.125:443 01-29 15:58:00.083 5486 5525 E chromium_net: external/chromium/net/socket/ssl_client_socket_openssl.cc:792: [0129/155800:ERROR:ssl_client_socket_openssl.cc(792)] handshake failed; returned 0, SSL error code 5, net_error -107 

我的应用程序还使用HttpClientHttpsUrlConnection类来设置SSL连接。在使用这些类时,我能够使用SSLSocket API来启用特定的协议。[http://developer.android.com/reference/javax/net/ssl/SSLSocket.html#setEnabledProtocols(java.lang.String[])](http://developer.android.com/reference/javax/net/ssl/SSLSocket.html#setEnabledProtocols(java.lang.String%5B%5D%29)

我也需要对WebViewClient做同样的事情。

EN

回答 4

Stack Overflow用户

发布于 2015-11-17 17:51:39

根据文档化,在Android < 4.3的WebView中不可能支持TLS1.0。对于Android4.4,默认情况下是禁用的。

查看此图表,以获得不同浏览器中对TLS1.0的支持:浏览器

票数 8
EN

Stack Overflow用户

发布于 2015-11-14 01:54:07

如果你的应用程序正在使用,或者你愿意使用Google服务,你可以通过安装他们的Provider在旧手机上使用更新的安全功能。它很容易安装,只有一行(加上异常处理,等等)。你还需要添加谷歌播放服务到你的梯度文件,如果你还没有它。ProviderInstaller包含在-base包中。

代码语言:javascript
复制
try {
    ProviderInstaller.installIfNeeded(this);
} catch (GooglePlayServicesRepairableException e) {
     // Fix it
} catch (GooglePlayServicesNotAvailableException e) {
     // Skip it
}

有关完整的示例,请参阅Google的“更新您的安全提供程序以防止SSL攻击”

票数 3
EN

Stack Overflow用户

发布于 2016-07-27 12:04:27

实际上,我设法使它工作,但您需要okHttp库。当您设置浏览器活动时,请尝试这样做:

代码语言:javascript
复制
    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);

此外,您还需要经典的信任管理器操作器、SSL套接字工厂及其在应用程序类中的实现:

代码语言:javascript
复制
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插座工厂:

代码语言:javascript
复制
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类:

代码语言:javascript
复制
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();
        }
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28329652

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档