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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24357863/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:03:25  来源:igfitidea点击:

Making SSLEngine use TLSv1.2 on Android (4.4.2)?

androidsslengine

提问by Glen

Folks, I'm hoping there's something obvious that I'm missing, and I hope someone will be able to shed some light. I'm trying to get TLSv1.2 running in an SSL + NIO context (using the AndroidAsynclibrary), so I'm trying to enable it via an SSLEngine. I can run code like this:

伙计们,我希望我遗漏了一些明显的东西,我希望有人能够阐明一些观点。我试图让 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);
        }

And I end up seeing this on logcat:

我最终在 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

Of course if I try to engine.setEnabledProtocols(new String[] { "TLSv1.2" })I get an IllegalArgumentException "Protocol TLSv1.2 is not supported."

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

I can see the context claims to support TLSv1.2, but then the engine I make from that context doesn't? What's going on here? None of this changes if I use "TLS" instead of "TLSv1.2" in the first line above, btw.

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

I gather this might have something to do with this issue, and I've read this (as yet unanswered) questionand articles like this, but they don't quite seem to be hitting the spot - solutions I've seen all seem to rely on SSLSocket rather than SSLEngine.

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

Thanks much for any knowledge you can drop.

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

UPDATE 6/23/14 10AMEDT

更新 6/23/14 10AMEDT

So I found SSLEngine.setSSLParameters, which I was hoping would let me pass in an SSLParameters that I got from SSLContext.getSupportedSSLParameters(), but when I call that I get an exception that claims the cipher suites aren't supported, so it looks like setSSLParameters() is just doing the same thing that setEnabledCipherSuites() does, and the engine is already in a state where it doesn't recognize the TLS 1.2 protocol/suites as supported.

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

回答by Wolfgang Profer

The Android API docs correctly statethat TLSv1.2 is only supported for SSLEngine in API Level 20 or later (Lollipop) while SSLSocket supports it since level 16.

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

Using SSLSocket or requiring API 20 was no option for our project and neither was changing the server code to allow TLSv1 or SSLv3. Our solution was to install a newer security provider using Google Play Services:

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

    ProviderInstaller.installIfNeeded(getApplicationContext());

This effectively gives your app access to a newer version of OpenSSL and Java Security Provider which includes support for TLSv1.2 in SSLEngine. Once the new provider is installed, you can create an SSLEngine which supports SSLv3, TLSv1, TLSv1.1 and TLSv1.2 the usual way:

这有效地使您的应用程序可以访问更新版本的 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();

Or you can restrict the enabled protocols using engine.setEnabledProtocols.

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

回答by AAnkit

Try this solution if you are using okHttp. Solution for enabling TLSv1.2 on Android 4.4

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

Had the same issue on Android < 5.0 (16 <= API < 20). Thanks to your posts, I was able to make this work, so for anyone who gets here, this is the out-of-the-box solution. At the time of this writing, I'm using OkHttp 3.4.1.

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

Tags : Unable to find acceptable protocols, javax.net.ssl.SSLProtocolException: SSL handshake aborted:

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

回答by Jordan Réjaud

Here is how to do in with AndroidAsync:

以下是如何使用 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); 

Updating SSLEngine and inserting it as middleware into AndroidAsync seems to work.

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