异常如下

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. python3-列表中存储字典

    # Auther: Aaron Fan #示例1:#定义几个字典alien_0 = {"color":"green", "points":5 ...

  2. [译]Javascript中的循环

    本文翻译youtube上的up主kudvenkat的javascript tutorial播放单 源地址在此: https://www.youtube.com/watch?v=PMsVM7rjupU& ...

  3. Linux中的sed解析

    简介 sed 是一种在线编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的 ...

  4. Gym - 100792C Colder-Hotter(三分交互)

    Colder-Hotter Statements This is an interactive problem. Egor and Petr are playing a game called «Co ...

  5. sql 根据指定字符截取前面几个字符

    1.找到指定字所在的位置并且减去多少是要截取的字符长度 CharIndex('元',product_name)-3) 2.截取 SUBSTRING(product_name, CharIndex('元 ...

  6. 【C#】如何打开Model Browser(实体数据模型浏览器)

    Visual Studio 2017 如何打开Model Browser(实体数据模型浏览器) 2017-10-11 十有三 2 浏览:4956 开发工具 Visual Studio 做个笔记,记录下 ...

  7. Mybatis基于代理Dao实现CRUD操作 及 Mybatis的参数深入

    Mybatis基于代理Dao实现CRUD操作 使用要求: 1.持久层接口和持久层接口的映射配置必须在相同的包下 2.持久层映射配置中mapper标签的namespace属性取值必须是持久层接口的全限定 ...

  8. asp遍历前端的所有控件

    //遍历ID为Panel1的panel里的所有label控件 foreach (Control ctl in this.Panel1.Controls) { //判断类型为Label的 if (ctl ...

  9. oracle数据库性能

    性能视图V$开头 V$SYSTEM_EVENT 正在等待的资源的系统信息 V$SESSION_EVENT 会话累计发生的等待事件 V$SESSION_WAIT 会话正在等待或者曾经等待的详细时间信息 ...

  10. window.performance

    利用window.performance查看网页性能 一般我们可以通过浏览器的调试工具-网络面板,或者代理工具查看网页加载过程中的各个阶段的耗时.而利用window.performance属性则可以获 ...