Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/183.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Android WebViewClient启用特定的SSL协议_Java_Android_Ssl_Https_Webviewclient - Fatal编程技术网

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

Java 使用Android WebViewClient启用特定的SSL协议,java,android,ssl,https,webviewclient,Java,Android,Ssl,Https,Webviewclient,我的应用程序使用WebViewClient与服务器建立SSL连接。 服务器配置为仅接受TLSv1.1及以上协议 1) 在设备上使用Android WebViewClient时,如何检查默认情况下支持和启用了哪些SSL协议 2) 如何为应用程序中使用的Android WebViewClient实例启用特定的SSL协议 在运行Android 4.3的其中一台测试设备上, WebViewClient引发onReceivedError回调,其描述为“未能执行SSL握手” Chrome日志如下: 01-2

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

1) 在设备上使用Android WebViewClient时,如何检查默认情况下支持和启用了哪些SSL协议
2) 如何为应用程序中使用的Android WebViewClient实例启用特定的SSL协议

在运行Android 4.3的其中一台测试设备上, WebViewClient引发onReceivedError回调,其描述为“未能执行SSL握手”
Chrome日志如下:
01-29 15:58:00.073 5486 5525 W chromium_-net:外部/chromium/net/http/http_-stream_-factory_-impl_-job.cc:865:[0129/155800:警告:http_-stream_-factory_-impl_-job.cc(865)]返回SSLv3,因为主机不能容忍TLS:10.209.126.125:443 01-29 15:58:00.083 5486 5525 E chromium_-net:外部/chromium/net/socket/ssl_-client_-socket_-openssl.cc:792:[0129/155800:错误:ssl\u client\u socket\u openssl.cc(792)]握手失败;返回0,ssl错误代码5,网络错误-107

我的应用程序还使用HttpClient和HttpsUrlConnection类来设置SSL连接。


我也需要对WebViewClient执行同样的操作。

如果您的应用程序正在使用或愿意使用Google Play服务,您可以通过安装其
提供商
在旧手机上使用更新的安全功能。只需一行即可轻松安装(加上异常处理等)。如果您还没有google play服务,您还需要将其添加到您的gradle文件中。
ProviderInstaller
包含在
-base
包中

try {
    ProviderInstaller.installIfNeeded(this);
} catch (GooglePlayServicesRepairableException e) {
     // Fix it
} catch (GooglePlayServicesNotAvailableException e) {
     // Skip it
}

有关完整示例,请参阅Google。

根据文档说明,在Android<4.3的WebView中不可能支持TLS 1.0。对于Android 4.4,默认情况下禁用TLS 1.0


查看此图表以了解在不同浏览器中对TLS 1.0的支持:

实际上,我已设法使其正常工作,但您需要okHttp库。 设置浏览器活动时,请尝试以下操作:

    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);
此外,您还需要经典的Trust Manager操纵器、SSL套接字工厂及其在应用程序类中的实现:

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套接字工厂:

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;
    }
}
应用程序类别:

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();
        }
    }
}

因为安卓4.3不支持TSL1.1,只支持TSL1.0 阅读这篇文章 查找android 4.3将看到

协议 TLS 1.3号 TLS 1.2号 TLS 1.1号 TLS 1.0是 SSL 3不安全是
SSL 2否

AFAIK启用的协议WebView不能由应用程序保存。支持或不支持哪些协议取决于Android版本。对于TLS 1.1及更高版本,您需要Android 4.4或更高版本(请参阅)。有人知道这一点吗?我正在做一个项目,目前我们需要从TLS v1.2退到1.1,用于三个非生产测试服务器。我们正在尝试使用类似的东西:adb shell“echo”浏览器--show fps counter--ssl version min=tls1.1--ssl version max=tls1.1”>/data/local/tmp/webview命令行“FPS计数器在Android L平板电脑上显示,但在Android TV上不显示(这很奇怪,因为它们应该是相同的webview代码)。ssl版本标志似乎不起作用;从设备捕获的tcpdump仍然显示正在使用TLS v1.2。任何帮助都会很好。@user802467您找到问题的解决方案了吗?我也面临同样的问题issue@KK_07k11A0585不,我找不到在WebViewClient中配置的方法。我认为上面Robert的评论是正确的。注意:这s是在主线程(UI线程)上调用的同步调用。您可以在后台运行的SyncAdapter或AsyncTask中运行此调用以执行此更新尝试,或使用此调用的installIfNeededAsync版本进行调用以避免阻塞主线程。此外,即使在成功安装提供程序后,您也需要显式启用TLS 1.2/TLS 1.1,同时在[16-20]之间的ndroid版本。我在KITKAT设备上验证了这一点。注意:这似乎无法解决4.1.2客户端的问题。@frank我设法使其工作的最低版本是4.4.2。拦截套接字创建并调用
setEnabledProtocols
似乎是唯一的解决方案。这对任何人都有效吗?我注意到我的4.4设备不再加载LS 1.2服务内容。您的意思是“…支持TLS 1.1”(而不是1.0)?它说默认情况下禁用
从4.1到4.4。那么如何启用它呢?不幸的是,我在我的webView中只看到纯文本;这可能取决于javaScript的执行。还发现了这篇文章@ar-g你解决了你的问题吗?如果你解决了,请告诉我。@AlexanderZarovniy问题是在第三方服务中,我们在4.4以下的android上使用不同的方案(与android无关)欢迎这么说。你的回答似乎与OP上的第一条评论基本相同。请参阅以获取指导。