制作SSLEngine在Android(4.4.2)上使用TLSv1.2?

时间:2014-06-23 02:58:48

标签: android sslengine

伙计们,我希望有一些显而易见的东西让我失踪,我希望有人能够解决问题。我试图让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"在上面的第一行,顺便说一句。

我认为这可能与this issue有关,而且我已经阅读了this (as yet unanswered) questionarticles like this,但他们似乎没有达到现场 - 解决方案我已经看到所有人似乎都依赖SSLSocket而不是SSLEngine。

非常感谢您可以放弃任何知识。

更新6/23/14 10AMEDT

所以我找到了SSLEngine.setSSLParameters,我希望能让我通过我从SSLContext.getSupportedSSLParameters()获得的SSLParameters,但是当我打电话给我时,我得到一个例外,声称密码套件不是&#39 ; t支持,所以看起来setSSLParameters()只是做与setEnabledCipherSuites()相同的事情,并且引擎已经处于一种状态,它不能识别支持的TLS 1.2协议/套件。

3 个答案:

答案 0 :(得分:60)

Android API文档correctly state TLSv1.2仅支持API级别20或更高版本(Lollipop)中的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限制启用的协议。

答案 1 :(得分:4)

如果您使用的是okHttp,请尝试此解决方案。 Solution for enabling TLSv1.2 on Android 4.4

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

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

答案 2 :(得分: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中似乎可行。