26

伙计们,我希望我遗漏了一些明显的东西,我希望有人能够提供一些启示。我试图让 TLSv1.2 在 SSL + NIO 上下文中运行(使用AndroidAsync库),所以我试图通过 SSLEngine 启用它。我可以运行这样的代码:

        SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
        sslContext.init(null, null, null);
        String[] protocols = sslContext.getSupportedSSLParameters().getProtocols();
        for (String protocol : protocols) {
            Timber.d("Context supported protocol: " + protocol);
        }

        SSLEngine engine = sslContext.createSSLEngine();
        String[] supportedProtocols = engine.getSupportedProtocols();
        for (String protocol : supportedProtocols) {
            Timber.d("Engine supported protocol: " + protocol);
        }

我最终在 logcat 上看到了这个:

06-22 21:56:27.715    1117-1117/? D/XXX﹕ Context supported protocol: SSLv3
06-22 21:56:27.715    1117-1117/? D/XXX﹕ Context supported protocol: TLSv1
06-22 21:56:27.725    1117-1117/? D/XXX﹕ Context supported protocol: TLSv1.1
06-22 21:56:27.725    1117-1117/? D/XXX﹕ Context supported protocol: TLSv1.2
06-22 21:56:27.735    1117-1117/? D/XXX﹕ Engine supported protocol: TLSv1
06-22 21:56:27.745    1117-1117/? D/XXX﹕ Engine supported protocol: SSLv3

当然,如果我尝试engine.setEnabledProtocols(new String[] { "TLSv1.2" })得到 IllegalArgumentException “不支持协议 TLSv1.2”。

我可以看到上下文声称支持 TLSv1.2,但是我从该上下文制作的引擎不支持?这里发生了什么?如果我在上面的第一行中使用“TLS”而不是“TLSv1.2”,这些都不会改变,顺便说一句。

我认为这可能与这个问题有关,并且我已经阅读了这个(尚未回答的)问题类似的文章,但它们似乎并没有达到目的 - 我见过的所有解决方案似乎都依赖 SSLSocket 而不是 SSLEngine。

非常感谢您提供的任何知识。

更新 6/23/14 10AMEDT

所以我找到SSLEngine.setSSLParameters了,我希望它能让我传入我从中获得的 SSLParameters SSLContext.getSupportedSSLParameters(),但是当我调用它时,我得到一个声称不支持密码套件的异常,所以看起来 setSSLParameters() 只是在做与 setEnabledCipherSuites() 所做的相同,并且引擎已经处于无法将 TLS 1.2 协议/套件识别为受支持的状态。

4

3 回答 3

66

Android API 文档正确地指出,TLSv1.2 仅支持 API 级别 20 或更高版本(棒棒糖)中的 SSLEngine,而 SSLSocket 从级别 16 开始支持它。

使用 SSLSocket 或要求 API 20 对我们的项目来说不是选项,也没有更改服务器代码以允许 TLSv1 或 SSLv3。我们的解决方案是使用Google Play Services安装更新的安全提供程序:

    ProviderInstaller.installIfNeeded(getApplicationContext());

这有效地使您的应用程序可以访问更新版本的 OpenSSL 和 Java 安全提供程序,其中包括对 SSLEngine 中的 TLSv1.2 的支持。安装新的提供程序后,您可以按通常的方式创建支持 SSLv3、TLSv1、TLSv1.1 和 TLSv1.2 的 SSLEngine:

    SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
    sslContext.init(null, null, null);
    SSLEngine engine = sslContext.createSSLEngine();

或者您可以使用 限制启用的协议engine.setEnabledProtocols

于 2014-10-27T11:13:38.343 回答
7

如果您使用的是 okHttp,请尝试此解决方案。 Android 4.4上启用TLSv1.2的解决方案

在 Android < 5.0 (16 <= API < 20) 上有同样的问题。多亏了您的帖子,我才得以完成这项工作,因此对于任何来到这里的人来说,这是开箱即用的解决方案。在撰写本文时,我使用的是 OkHttp 3.4.1。

标签:无法找到可接受的协议,javax.net.ssl.SSLProtocolException:SSL 握手中止:

于 2017-02-09T08:00:21.270 回答
3

以下是使用 AndroidAsync 的方法:

ProviderInstaller.installIfNeeded(context);
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(KeyManager[] km, TrustManager[] tm, SecureRandom rm);
SSLEngine engine = sslContext.createSSLEngine();
AsyncHttpClient.getDefaultInstance().insertMiddleware((AsyncHttpClientMiddleware) engine); 

更新 SSLEngine 并将其作为中间件插入 AndroidAsync 似乎可行。

于 2015-09-19T20:29:00.587 回答