让 SSLEngine 在 Android (4.4.2) 上使用 TLSv1.2?
Posted
技术标签:
【中文标题】让 SSLEngine 在 Android (4.4.2) 上使用 TLSv1.2?【英文标题】:Making SSLEngine use TLSv1.2 on Android (4.4.2)? 【发布时间】:2014-08-13 00:25:09 【问题描述】:伙计们,我希望我缺少一些明显的东西,我希望有人能够提供一些启示。我试图让 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) question 和 articles like this,但它们似乎并不完全正确 - 我见过的所有解决方案似乎都是依赖 SSLSocket 而不是 SSLEngine。
非常感谢您提供的任何知识。
2014 年 6 月 23 日更新 10AMEDT
所以我找到了SSLEngine.setSSLParameters
,我希望它能让我传入从SSLContext.getSupportedSSLParameters()
获得的 SSLParameters,但是当我调用它时,我得到一个异常,声称不支持密码套件,所以它看起来 setSSLParameters() 只是在做与 setEnabledCipherSuites() 相同的事情,并且引擎已经处于无法识别支持的 TLS 1.2 协议/套件的状态。
【问题讨论】:
当您执行sslContext.setEnabledProtocols(new String[] "TLSv1.2" )
,然后执行sslContext.createSSLEngine();
时会发生什么?
SSLContext 没有 setEnabledProtocols() API。但是,我确实发现了 SSLEngine.setSSLParameters()。即将编辑问题。
嗨,格伦,我很困惑这个问题,你能帮帮我吗? ***.com/questions/49946350/…
【参考方案1】:
如果您使用的是 okHttp,请尝试此解决方案。 Solution for enabling TLSv1.2 on Android 4.4
在 Android
标签:无法找到可接受的协议,javax.net.ssl.SSLProtocolException:SSL 握手中止:
【讨论】:
哇!太好了,它解决了我 4 天以来的问题,谢谢 Wolfgang Profer【参考方案2】:以下是使用 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 似乎可行。
【讨论】:
解释一下为什么这个解决方案有效会很有帮助,至少是您博客文章的解释。 @JordanRéjaud 从哪里传入上下文? 我认为在 Ion 中设置 SSLContext 可能会更好:Ion.getDefault(this).getHttpClient().getSSLSocketMiddleware().setSSLContext(sslContext);【参考方案3】:Android API 文档correctly state TLSv1.2 仅支持 API 级别 20 或更高版本的 SSLEngine (Lollipop),而 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
限制启用的协议。
【讨论】:
您好,感谢您的回答!这还不是我们尝试过的事情,将在接下来的几天内尝试这样做,然后将其标记为已接受。 你好!我们如何将它与 Android 上的 HttpsUrlConnection 一起使用? 伙计,你太棒了! ProviderInstaller.installIfNeeded(getApplicationContext());这就是为什么我的应用无法在 4.0 的 android 上运行 您知道是否有任何方法可以在 AVD 上使用例如 api 18 进行测试?我用 api 18 + Google API 创建了一个 AVD。在这种情况下,我看到 SSLEngine 与 TLS v1 和 3 仅可用。当我添加“ProviderInstaller”和谷歌服务依赖项时,我得到了安装升级的对话框,但由于它是一个 AVD,我没有通过那个屏幕。 嘿,你真的救了我:),非常感谢!以上是关于让 SSLEngine 在 Android (4.4.2) 上使用 TLSv1.2?的主要内容,如果未能解决你的问题,请参考以下文章
Play Framework 中的 SSL 导致“常规 SSLEngine 问题”。 (nginx)
oracle.jdbc.driver.OracleDriver。 IO 错误:尝试将 liquibase 连接到 Oracle RDS 时出现 IO 错误 一般 SSLEngine 问题