伙计们,我希望有一些显而易见的东西让我失踪,我希望有人能够解决问题。我试图让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。
非常感谢您可以放弃任何知识。
更新6/23/14 10AMEDT
所以我找到了SSLEngine.setSSLParameters
,我希望能让我通过我从SSLContext.getSupportedSSLParameters()
获得的SSLParameters,但是当我打电话给我时,我得到一个例外,声称密码套件不是&#39 ; t支持,所以看起来setSSLParameters()只是做与setEnabledCipherSuites()相同的事情,并且引擎已经处于一种状态,它不能识别支持的TLS 1.2协议/套件。
答案 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中似乎可行。