Android 4.4 以下,OkHttp访问Https报错,设置了sslSocketFactory仍无效的解决方法

背景

Android 4.4 及以下,使用 OkHttp 发送 Https 请求,报以下错误:

    javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6b712c90: Failure in SSL library, usually a protocol errorerror:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0x68111cd4:0x00000000)at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:448)at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:302)at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:270)at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:162)at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)at okhttp3.RealCall$AsyncCall.execute(RealCall.java:147)at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)at java.lang.Thread.run(Thread.java:841)Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6b712c90: Failure in SSL library, usually a protocol errorerror:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0x68111cd4:0x00000000)at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:405)... 23 more

一、确保OkHttp的Https配置正确

首先配制好 sslSocketFactory 和 hostnameVerifier:

import android.annotation.SuppressLint
import java.net.InetAddress
import java.net.Socket
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocket
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManagerclass MySSLSocketFactory(tm: TrustManager = TrustAllTrustManager()) : SSLSocketFactory() {var internalSSLSocketFactory: SSLSocketFactoryvar context: SSLContext = SSLContext.getInstance("TLSv1.1")init {context.init(null, arrayOf(tm), null)internalSSLSocketFactory = context.socketFactory}override fun getDefaultCipherSuites(): Array<String> {return internalSSLSocketFactory.defaultCipherSuites}override fun createSocket(s: Socket?, host: String?, port: Int, autoClose: Boolean): Socket {val sslSocket = context.socketFactory?.createSocket(s, host, port, autoClose) as SSLSocketsslSocket.enabledProtocols = arrayOf("TLSv1.2", "TLSv1.1")return sslSocket}override fun getSupportedCipherSuites(): Array<String> {return internalSSLSocketFactory.supportedCipherSuites}override fun createSocket(host: String?, port: Int): Socket {val sslSocket = context.socketFactory?.createSocket(host, port) as SSLSocketsslSocket.enabledProtocols = arrayOf("TLSv1.2", "TLSv1.1")return sslSocket}override fun createSocket(host: String?, port: Int, localHost: InetAddress?, localPort: Int): Socket {val sslSocket = context.socketFactory?.createSocket(host, port, localHost, localPort) as SSLSocketsslSocket.enabledProtocols = arrayOf("TLSv1.2", "TLSv1.1")return sslSocket}override fun createSocket(host: InetAddress?, port: Int): Socket {val sslSocket = context.socketFactory?.createSocket(host, port) as SSLSocketsslSocket.enabledProtocols = arrayOf("TLSv1.2", "TLSv1.1")return sslSocket}override fun createSocket(address: InetAddress?, port: Int, localAddress: InetAddress?, localPort: Int): Socket {val sslSocket = context.socketFactory?.createSocket(address, port, localAddress, localPort) as SSLSocketsslSocket.enabledProtocols = arrayOf("TLSv1.2", "TLSv1.1")return sslSocket}@SuppressLint("CustomX509TrustManager", "TrustAllX509TrustManager")class TrustAllTrustManager : X509TrustManager {@Throws(CertificateException::class)override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {}@Throws(CertificateException::class)override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {}override fun getAcceptedIssuers(): Array<X509Certificate> {return arrayOf()}}
}public class SSLSocketClient {//获取这个SSLSocketFactorypublic static SSLSocketFactory getSSLSocketFactory() {try {SSLContext sslContext = SSLContext.getInstance("SSL");sslContext.init(null, getTrustManager(), new SecureRandom());return sslContext.getSocketFactory();} catch (Exception e) {throw new RuntimeException(e);}}//获取TrustManagerprivate static TrustManager[] getTrustManager() {return new TrustManager[]{new X509TrustManager() {@Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType) {}@Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType) {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}}};}//获取HostnameVerifierpublic static HostnameVerifier getHostnameVerifier() {HostnameVerifier hostnameVerifier = new HostnameVerifier() {@Overridepublic boolean verify(String s, SSLSession sslSession) {return true;}};return hostnameVerifier;}
}

在OkHttp中使用:

    val tm = TrustAllTrustManager()val client = OkHttpClient.Builder().sslSocketFactory(MySSLSocketFactory(tm), tm).hostnameVerifier(SSLSocketClient.getHostnameVerifier()).build()val request = Request.Builder().url(url).build()client.newCall(request).enqueue(object : Callback {override fun onFailure(call: Call, e: IOException) {Log.w(TAG, "onFailure: ", e)onResult(Log.getStackTraceString(e))}override fun onResponse(call: Call, response: Response) {val result = response.body()?.string()onResult(result)}})

二、仍然报错的解决方案

如果通过以上的配置,仍然报 Failure in SSL library, usually a protocol error 的错,则有以下两种解决方案:

1. 降级OkHttp

将 OkHttp 降级到 3.9.0,即可正常请求。

2. 配置ConnectionSpec

在 OkHttpClient 创建的过程中,添加 ConnectionSpec 的配置,如下:

    // ConnectionSpec的配置val spec = ConnectionSpec.Builder(ConnectionSpec.COMPATIBLE_TLS).tlsVersions(TlsVersion.TLS_1_2, TlsVersion.TLS_1_1, TlsVersion.TLS_1_0).cipherSuites(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA).build()val tm = TrustAllTrustManager()val client = OkHttpClient.Builder().connectionSpecs(Collections.singletonList(spec)).sslSocketFactory(MySSLSocketFactory(tm), tm).hostnameVerifier(SSLSocketClient.getHostnameVerifier()).build()val request = Request.Builder().url(url).build()client.newCall(request).enqueue(object : Callback {override fun onFailure(call: Call, e: IOException) {Log.w(TAG, "onFailure: ", e)onResult(Log.getStackTraceString(e))}override fun onResponse(call: Call, response: Response) {val result = response.body()?.string()onResult(result)}})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/729029.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Jemter】安装

1.准备前提工作 2.安装和卸载jdk 1&#xff09;安装双击jdk 2&#xff09;添加环境变量 此电脑–属性–高级系统设置–环境变量–系统变量–path删除/新建 C:\Program Files\Java\jdk-1.8\bin C:\Program Files\Java\jdk-1.8\jre 3&#xff09;验证 以防万一要卸载&#xff…

基于yolov5的铁轨缺陷检测系统,可进行图像目标检测,也可进行视屏和摄像检测(pytorch框架)【python源码+UI界面+功能源码详解】

功能演示&#xff1a; 基于yolov5的铁轨缺陷检测系统&#xff0c;系统既能够实现图像检测&#xff0c;也可以进行视屏和摄像实时检测_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于yolov5的铁轨缺陷检测系统是在pytorch框架下实现的&#xff0c;这是一个完整的项目…

Vue 使用Element Plus

1.官网安装 | Element PlusA Vue 3 based component library for designers and developershttps://element-plus.gitee.io/zh-CN/guide/installation.html#%E4%BD%BF%E7%94%A8%E5%8C%85%E7%AE%A1%E7%90%86%E5%99%A8 npm install element-plus --save2. 全局安装图标 npm ins…

如何避免前端请求明文传输

要在前端发送请求时做到不明文&#xff0c;有以下几种方法&#xff1a; HTTPS 加密传输&#xff1a; 使用 HTTPS 协议发送请求&#xff0c;所有的数据都会在传输过程中进行加密&#xff0c;从而保护数据不以明文形式传输。这样即使数据被截获&#xff0c;黑客也无法直接获取到数…

连接kafka报错:java.io.IOException: Can‘t resolve address:

修改电脑host文件:C:\Windows\System32\drivers\etc\hosts 加上一行 192.168.1.XXX MHA_SLAVE2&#xff08;192.168.1.XXX 这个是安装kafka 的服务器地址&#xff0c;MHA_SLAVE2是kafka的容器id&#xff09;

总结虚拟机的安装步骤:

总结虚拟机的安装配置步骤 保障镜像的基本完整&#xff0c;查看其镜像源是否是完整的&#xff0c;不能使用redhat的配置&#xff0c;原因在于其yum源中可能存在一些配置的消失。然后开始安装虚拟机&#xff0c;虚拟机的软件版本越高其运行的效果也就越好&#xff0c;在进入初始…

极狐GitLab 16.2 重点功能解读,更好的DevOps体验等你来【二】

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 极狐GitLab 在去年 7 月份发布了 16.2 版本。此次发布带来了价…

构建可视化工具选择策略

更多的信息总是意味着更好的结果吗&#xff1f;这完全取决于项目所处的环境。 以烘焙为例。当你做蛋糕时&#xff0c;你的原材料经历了许多化学变化和烹制过程。如果任何一个环节出现问题&#xff0c;蛋糕就做不好。但这并不意味着你需要理解食材在分子级别上发生了什么&#…

科技云报道:阿里云降价,京东云跟进,谁能打赢云计算价格战?

科技云报道原创。 就在大家还在回味2月29日阿里云发布“史上最大降价”的惊喜时&#xff0c;京东云连夜发布降价消息&#xff0c;成为第一家跟进的云服务商&#xff0c;其“随便降&#xff0c;比到底&#xff01;”的口号&#xff0c;颇有对垒的意味&#xff0c;直接吹响了云计…

阿里巴巴中国站1688商品详情API:获取数据的关键步骤与技巧

阿里巴巴中国站&#xff08;1688.com&#xff09;是一个大型的B2B电商平台&#xff0c;提供了丰富的商品信息。然而&#xff0c;关于商品详情API的具体使用&#xff0c;通常需要注册成为阿里巴巴的开发者并遵循其API开发文档进行操作。由于API的具体实现和接口可能会随时间变化…

用skopeo检查docker image

文章目录 环境 环境 OCP 4.14.12 yum install skopeo -y在 ibm-dmc-bundle/stable/ibm-dmc-bundle/build/operand_images 处&#xff0c;找到digest号。 比如&#xff0c;找到这一行&#xff1a; DMC_ADDON_API_IMAGE_DIGEST_amd64sha256:f8208890bf4058e17223afe1c40a29df…

java 从零开始手写 RPC (00) 概览 overview

rpc rpc 是基于 netty 实现的 java rpc 框架&#xff0c;类似于 dubbo。 主要用于个人学习&#xff0c;由渐入深&#xff0c;理解 rpc 的底层实现原理。 特性 基于 netty4 的客户端调用服务端 p2p 调用 serial 序列化支持 timeout 超时处理 register center 注册中心 l…

retinaNet FocalLoss源码详解

targets[positive_indices, assigned_annotations[positive_indices, 4].long()] 1 ## 把正样本所对应的锚框所对应的类别的列置为1 # aim torch.randint(0, 1, (1, 80)) # tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 0…

react tab选项卡吸顶实现

react tab选项卡吸顶实现&#xff0c;直接上代码&#xff08;代码有注释&#xff09; tsx代码 /* eslint-disable react-hooks/exhaustive-deps */ import React, { useEffect, useState } from "react"; import DocumentTitle from react-document-title import s…

智奇科技工业 Linux 屏更新开机logo

智奇科技工业 Linux 屏更新开机logo 简介制作logo.img文件1、转换格式得到logo.bmp2、使用Linux命令生成img文件 制作rootfs.img文件替换rootfs.img中的logo 生成update.img固件附件 简介 智奇科技的 Linux 屏刷开机logo必须刷img镜像文件&#xff0c;比较复杂。 制作logo.i…

Python教程,python从入门到精通 第1天 温习笔记

1.1 字面量 1.2 注释 1.3 变量 1.4 数据类型 1.5 数据类型转换 1.6 标识符 1.7 运算符 1.8 字符串的三种定义方式 1.9 字符串拼接 1.10 字符串格式化 1.11 掌握格式化字符串的过程中做数字的精度控制 1.12 掌握快速字符串格式化的方式 1.13 字符串格式化&#xff0d;表达式的格…

《MySQL实战45讲》课程大纲

1MySQL实战45讲-01基础架构&#xff1a;一条SQL查询语句是如何执行的&#xff1f;2MySQL实战45讲-02日志系统&#xff1a;一条SQL更新语句是如何执行的&#xff1f;3MySQL实战45讲-03事务隔离&#xff1a;为什么你改了我还看不见&#xff1f;4MySQL实战45讲-04深入浅出索引&…

【C++干货基地】六大默认成员函数: This指针 | 构造函数 | 析构函数

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 引入 哈喽各位铁汁们好啊&#xff0c;我是博主鸽芷咕《C干货基地》是由我的襄阳家乡零食基地有感而发&#xff0c;不知道各位的…

Redis冲冲冲——redis数据类型及对应的数据结构

目录 引出redis数据类型及对应的数据结构Redis入门1.Redis是什么&#xff1f;2.Redis里面存Java对象 Redis进阶1.雪崩/ 击穿 / 穿透2.Redis高可用-主从哨兵3.持久化RDB和AOF4.Redis未授权访问漏洞5.Redis里面安装BloomFilte Redis的应用1.验证码2.Redis高并发抢购3.缓存预热用户…

PaddleOCR识别框架解读[07] 文本检测

文章目录 1. 准备数据和模型1.1 准备数据集1.2 下载预训练模型2. 开始训练2.1 启动训练2.2 断点训练2.3 更换Backbone 训练2.4 混合精度训练2.5 分布式训练2.6 知识蒸馏训练2.7 其他训练环境2.8 模型微调3. 模型评估与预测3.1 指标评估3.2 测试检测效果4. 模型