https Android 5.0 以下TLS 版本过低造成的问题
异常如下
javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x610df808: Failure in SSL library, usually a protocol error
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0x410f976a:0x00000000)
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:412)
at okhttp3.internal.connection.RealConnection.connectTls(Paramount:281)
at okhttp3.internal.connection.RealConnection.establishProtocol(Paramount:251)
at okhttp3.internal.connection.RealConnection.connect(Paramount:151)
at okhttp3.internal.connection.StreamAllocation.findConnection(Paramount:192)
at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(Paramount:121)
at okhttp3.internal.connection.StreamAllocation.newStream(Paramount:100)
at okhttp3.internal.connection.ConnectInterceptor.intercept(Paramount:42)
at okhttp3.internal.http.RealInterceptorChain.proceed(Paramount:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(Paramount:67)
at okhttp3.internal.cache.CacheInterceptor.intercept(Paramount:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(Paramount:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(Paramount:67)
at okhttp3.internal.http.BridgeInterceptor.intercept(Paramount:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(Paramount:92)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(Paramount:120)
at okhttp3.internal.http.RealInterceptorChain.proceed(Paramount:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(Paramount:67)
at okhttp3.RealCall.getResponseWithInterceptorChain(Paramount:185)
at okhttp3.RealCall.execute(Paramount:69)
at com.qihoo.mm.paramount.tools.glide.j.b(Paramount:44)
at com.qihoo.mm.paramount.tools.glide.j.a(Paramount:21)
at com.bumptech.glide.load.b.f$a.b(Paramount:70)
at com.bumptech.glide.load.b.f$a.a(Paramount:53)
at com.bumptech.glide.load.engine.a.e(Paramount:170)
at com.bumptech.glide.load.engine.a.c(Paramount:128)
at com.bumptech.glide.load.engine.h.f(Paramount:122)
at com.bumptech.glide.load.engine.h.d(Paramount:101)
at com.bumptech.glide.load.engine.h.run(Paramount:58)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor$a$1.run(Paramount:118)
Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x610df808: Failure in SSL library, usually a protocol error
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0x410f976a:0x00000000)
at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:371)
... 35 more
由于集成的 SSL 库版本不同,不同 Android 版本的默认 SSL/TLS 版本配置如下表:
| Protocol | Supported (API Levels) | Enabled by default (API Levels) |
|---|---|---|
| SSLv3 | 1–TBD | 1–22 |
| TLSv1 | 1+ | 1+ |
| TLSv1.1 | 20+ | 20+ |
| TLSv1.2 | 20+ | 20+ |
在 Android 5.0 之前,最高支持的 SSL/TLS 版本为 TLSv1,而这个版本实际上是一个安全性并不是太好的版本,当前已经有许多网站配置为不再支持这种老版本的 SSL/TLS 。在用 Android 5.0 之前的设备,访问一些不再支持 TLSv1 及之前 SSL/TLS 版本的网站的时候,就会出现一些问题。
在 Android 4.3、Android 4.2.2 和 Android 4.1.1 上,用相同版本的 OkHttp 访问前面配置为最低支持 TLSv1.1 的 HTTP 服务器时,抛出了完全相同的异常。
客户端版本低于服务器支持的最低 SSL/TLS 版本时,HTTPS 连接会在握手阶段失败。
为请求的网络客户端设置一个特殊的SSLSocketFactory
import android.os.Build
import android.util.Log
import com.android.core.Arrays
import com.qihoo.mm.paramount.env.AppEnv
import okhttp3.OkHttpClient
import java.io.IOException
import java.net.InetAddress
import java.net.Socket
import java.net.UnknownHostException
import java.security.GeneralSecurityException
import java.security.KeyStore
import javax.net.ssl.*
public class Tls12SocketFactory extends SSLSocketFactory {
private static final String[] TLS_SUPPORT_VERSION = {"TLSv1.1", "TLSv1.2"}; final SSLSocketFactory delegate; public Tls12SocketFactory(SSLSocketFactory base) {
this.delegate = base;
} @Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
} @Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
} @Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return patch(delegate.createSocket(s, host, port, autoClose));
} @Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port));
} @Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port, localHost, localPort));
} @Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return patch(delegate.createSocket(host, port));
} @Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return patch(delegate.createSocket(address, port, localAddress, localPort));
} private Socket patch(Socket s) {
if (s instanceof SSLSocket) {
((SSLSocket) s).setEnabledProtocols(TLS_SUPPORT_VERSION);
}
return s;
}
}
修改默认X509TrustManager
private X509TrustManager getDefaultTrustManager() {
try {
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
}
return (X509TrustManager) trustManagers[0];
} catch (GeneralSecurityException e) {
throw new AssertionError(); // The system has no TLS. Just give up.
}
}
设置OkHttpClient
private OkHttpClient initOkHttpClient() {
OkHttpClient builder = OkHttpClient.Builder()
try {
if(DEBUG){
Log.i(TAG,"initOkHttpClient")
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
Tls12SocketFactory.enableTls12OnPreLollipop(builder)
}
builder.readTimeout(10L, TimeUnit.SECONDS)//设置读取超时时间
builder.writeTimeout(10L, TimeUnit.SECONDS)//设置写的超时时间
builder.connectTimeout(10L, TimeUnit.SECONDS)//设置连接超时时间
} catch (e: Exception) {
if(DEBUG){
Log.e(TAG,"",e)
}
}
return builder.build()
}
public static OkHttpClient.Builder enableTls12OnPreLollipop(OkHttpClient.Builder client) {
if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 22) {
try {
val sslContext = SSLContext.getInstance("TLS")
sslContext .init(null, null, null)
val socketFactory = Tls12SocketFactory(sslContext.socketFactory)
client.sslSocketFactory(socketFactory, getDefaultTrustManager())
} catch (exc: Exception) {
if (AppEnv.bAppdebug) {
Log.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc)
}
try {
SSLContext sc = SSLContext.getInstance("TLSv1.2");
sc.init(null, null, null);
client.sslSocketFactory(new Tls12SocketFactory(sc.getSocketFactory()));
client.sslSocketFactory(socketFactory, getDefaultTrustManager())
client.connectionSpecs(specs);
} catch (Exception exc) {
if (AppEnv.bAppdebug) {
Log.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc);
}
}
}
return client;
}
https Android 5.0 以下TLS 版本过低造成的问题的更多相关文章
- Android 6.0 M userdebug版本执行adb remount失败
[FAQ18076]Android 6.0 M版本默认会打开system verified boot,即在userdebug和user版本会把system映射到dm-0设备,然后再挂载.挂载前会检查s ...
- Android 5.0及以上版本使用webview不能存储第三方Cookies解决方案
Android 5.0以上的手机使用原生WebView浏览网页,在进行登录的时候会提示验证码错误,通过查找5.0以上系统的api文档,发现5.0以上版本的webview做了较大的改动,如:同步cook ...
- tomcat https 支持android 6.0及以上版本的配置方法
<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true" scheme ...
- Android 6.0及以上版本如何实现从图库中选取图片和拍照功能
XML 代码: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andr ...
- Android 4.0及以上版本接收开机广播BOOT_COMPLETED、开机自启动服务
1.BootCompletedReceiver.Java文件 public class BootCompletedReceiver extends BroadcastReceiver { @Overr ...
- Charles + Android 抓取Https数据包 (适用于Android 6.0及以下)
通过Charles代理,我们能很轻易的抓取手机的Http请求,因为Http属于明文传输,所以我们能直接获取到我们要抓取的内容.但是Https内容本身就是加密的,这时我们会发现内容是加密的了.本文我们来 ...
- Android 5.0 行为变更
Android 5.0 除了提供诸多新特性和功能外,还对系统和 API 行为做出了各种变更.本文重点介绍您应该了解并在开发应用时加以考虑的一些主要变更. 如果您之前发布过 Android 应用,请注意 ...
- android 8.0变更
Android 8.0 行为变更 Android 8.0 除了提供诸多新特性和功能外,还对系统和 API 行为做出了各种变更.本文重点介绍您应该了解并在开发应用时加以考虑的一些主要变更. 其中大部分变 ...
- android 8.0 适配(总结)
android 8.0 对应的 sdk 版本 26 1. 通知栏 Android 8.0 引入了通知渠道,其允许您为要显示的每种通知类型创建用户可自定义的渠道.用户界面将通知渠道称之为通知类别. 针 ...
随机推荐
- 实现斗地主纸牌游戏---洗牌 发牌 看底牌的具体功能------Map集合存储方法 遍历的应用
该Demo只是斗地主的游戏的一部分,实现的斗地主的组合牌 洗牌 发牌 看牌的功能,主要应用Map集合进行练习 package cn.lijun import java.util.ArrayList ...
- (数组)字符串的回文构词法( anagrams)
题目:https://www.nowcoder.com/practice/e84e273b31e74427b2a977cbfe60eaf4?tpId=46&tqId=29130&tPa ...
- 《Effective Java》第9章 异常
第58条:对可恢复的情况使用受检异常,对编程错误使用运行时异常 Java程序设计语言提供了三种可抛出结构(throwable) ;受检的异常(checked exception)运行时异常(run-t ...
- Glib学习笔记(二)
你将学到什么 如何实现Object的构造函数和析构函数 如何在条件检测不允许的情况下终止对象创建 Object的构造函数 对象的构造函数是不允许失败,如果你需要一个允许失败的GObject构造函数,使 ...
- History命令用法15例
以下内容为转载: 如果你经常使用 Linux 命令行,那么使用 history(历史)命令可以有效地提升你的效率.本文将通过实例的方式向你介绍 history 命令的 15 个用法. 使用 HISTT ...
- 洛谷P2518 [HAOI2010]计数
题目描述 你有一组非零数字(不一定唯一),你可以在其中插入任意个0,这样就可以产生无限个数.比如说给定{1,2},那么可以生成数字12,21,102,120,201,210,1002,1020,等等. ...
- Linux下oracle开机自启动服务
如果每次重启操作系统都要进行以上操作好麻烦,那么如何让Oracle作为系统服务在开机的时候自动启动呢? Oracle在$ORACLE_HOME/bin下提供许多对数据库进行操作的脚本,其中dbstar ...
- flink学习笔记-各种Time
说明:本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKh ...
- VUE使用微信JDK(附踩坑记录)
VUE使用微信分享SDK(附踩坑记录) 微信分享官方文档 安装JS-SDK npm i -S weixin-jsapi 引入包 ES5 写法 const wx = require('weixin-js ...
- CF1101A Minimum Integer 模拟
题意翻译 题意简述 给出qqq组询问,每组询问给出l,r,dl,r,dl,r,d,求一个最小的正整数xxx满足d∣x d | x\ d∣x 且x̸∈[l,r] x \not\in [l,r]x̸∈[l ...