异常如下

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 版本过低造成的问题的更多相关文章

  1. Android 6.0 M userdebug版本执行adb remount失败

    [FAQ18076]Android 6.0 M版本默认会打开system verified boot,即在userdebug和user版本会把system映射到dm-0设备,然后再挂载.挂载前会检查s ...

  2. Android 5.0及以上版本使用webview不能存储第三方Cookies解决方案

    Android 5.0以上的手机使用原生WebView浏览网页,在进行登录的时候会提示验证码错误,通过查找5.0以上系统的api文档,发现5.0以上版本的webview做了较大的改动,如:同步cook ...

  3. tomcat https 支持android 6.0及以上版本的配置方法

    <Connector port="443"  protocol="HTTP/1.1" SSLEnabled="true" scheme ...

  4. Android 6.0及以上版本如何实现从图库中选取图片和拍照功能

    XML 代码: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andr ...

  5. Android 4.0及以上版本接收开机广播BOOT_COMPLETED、开机自启动服务

    1.BootCompletedReceiver.Java文件 public class BootCompletedReceiver extends BroadcastReceiver { @Overr ...

  6. Charles + Android 抓取Https数据包 (适用于Android 6.0及以下)

    通过Charles代理,我们能很轻易的抓取手机的Http请求,因为Http属于明文传输,所以我们能直接获取到我们要抓取的内容.但是Https内容本身就是加密的,这时我们会发现内容是加密的了.本文我们来 ...

  7. Android 5.0 行为变更

    Android 5.0 除了提供诸多新特性和功能外,还对系统和 API 行为做出了各种变更.本文重点介绍您应该了解并在开发应用时加以考虑的一些主要变更. 如果您之前发布过 Android 应用,请注意 ...

  8. android 8.0变更

    Android 8.0 行为变更 Android 8.0 除了提供诸多新特性和功能外,还对系统和 API 行为做出了各种变更.本文重点介绍您应该了解并在开发应用时加以考虑的一些主要变更. 其中大部分变 ...

  9. android 8.0 适配(总结)

    android 8.0 对应的 sdk 版本  26 1. 通知栏 Android 8.0 引入了通知渠道,其允许您为要显示的每种通知类型创建用户可自定义的渠道.用户界面将通知渠道称之为通知类别. 针 ...

随机推荐

  1. 关于LIst Set Map 异常的知识点---我的笔记

    今天新的内容1.List接口2.Set接口3.Map集合4.异常==================================================================== ...

  2. Bootstrap 的 Modal

    一.简介 Modal 就是弹出框,这里 有一个例子. Modal 的完整代码如下: <div class="modal fade" tabindex="-1&quo ...

  3. 《Maven实战》笔记-10-灵活的构建

    一.灵活构建的意义 一个优秀的构建系统必须足够灵活,它应该能够让项目在不同的环境下都能成功地构建.例如,典型的项目都会有开发环境.测试环境和产品环境,这些环境的数据库配置不尽相同,那么项目构建的时候就 ...

  4. 第一个SpringMVC程序(最简单的)

      注册中央调度器,这个中央调度器就是org.springframework.web.servlet.DispatcherServlet这个类(web.xml servlet-name节点的名字,必须 ...

  5. Oracle中的学习笔记

    1.使用 ||来连接字符串 select CARD_ID ||','||CARD_TYPE as qqq from CARDS t 2.DISTINCT (唯一不重复) select DISTINCT ...

  6. uoj#453. 【集训队作业2018】围绕着我们的圆环(线性代数+递推)

    题面 传送门 题解 我对线代一无所知 如果下面有啥说错的地方请说出来省的我一辈子都搞不明白 如果你没看懂以下在讲什么不要紧,因为我也没看懂 首先,关于\(A\times B \equiv C \pmo ...

  7. (Python OpenGL)【5】平移 PyOpenGL

    (Python OpenGL) 原文:http://ogldev.atspace.co.uk/www/tutorial06/tutorial06.html  (英文) 下面是我翻译过来的: 背景 在本 ...

  8. 模板【洛谷P3390】 【模板】矩阵快速幂

    P3390 [模板]矩阵快速幂 题目描述 给定n*n的矩阵A,求A^k 矩阵A的大小为n×m,B的大小为n×k,设C=A×B 则\(C_{i,j}=\sum\limits_{k=1}^{n}A_{i, ...

  9. iOS沙盒文件目录

    iphone沙箱模型的有四个文件夹,分别是什么,永久数据存储一般放在什么位置,得到模拟器的路径的简单方式是什么.documents,tmp,app,Library.(NSHomeDirectory() ...

  10. SpriteBuilder 不能对设置spriteframe的sprite进行设置dynamic Physics解决办法

    可能spriteBuilder是最新推出 cocos2d 可视化,在学习过程中遇到一些Bug,比如你对一个精灵设置了一个动画帧(spriteframe),这并不会改变他的物理属性,正常来说是可以设置他 ...