在做超理论坛app的过程中,遇到许多用户反馈在他们的手机上客户端不能访问网络,我问了他们的手机型号和Android系统版本,全部是5.0以下的,之后我自己运行API19(4.4)的Android模拟器,也遇到了同样的错误。

错误信息如下:

javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x79f145b0: Failure in SSL library, usually a protocol errorerror:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version

因为之前没有太多接触过网络协议,这个问题也确实很难搜到,所以我找了很久,才找到了原因:Android 4.4及以下的系统默认不支持TLS协议,所以遇到使用TLS协议的网站就无法访问了。

解决方法如下:创建一个SSLSocketFactoryCompat.java文件,内容如下:

import java.io.IOException;

import java.net.InetAddress;

import java.net.Socket;

import java.net.UnknownHostException;

import java.security.GeneralSecurityException;

import java.util.Arrays;

import java.util.HashSet;

import java.util.LinkedList;

import java.util.List;

import javax.net.ssl.SSLContext;

import javax.net.ssl.SSLSocket;

import javax.net.ssl.SSLSocketFactory;

import javax.net.ssl.X509TrustManager;

public class SSLSocketFactoryCompat extends SSLSocketFactory {

private SSLSocketFactory defaultFactory;

// Android 5.0+ (API level21) provides reasonable default settings

// but it still allows SSLv3

// https://developer.android.com/about/versions/android-5.0-changes.html#ssl

static String protocols[] = null, cipherSuites[] = null;

static {

try {

SSLSocket socket = (SSLSocket)SSLSocketFactory.getDefault().createSocket();

if (socket != null) {

/* set reasonable protocol versions */

// - enable all supported protocols (enables TLSv1.1 and TLSv1.2 on Android <5.0)

// - remove all SSL versions (especially SSLv3) because they're insecure now

List protocols = new LinkedList<>();

for (String protocol : socket.getSupportedProtocols())

if (!protocol.toUpperCase().contains("SSL"))

protocols.add(protocol);

SSLSocketFactoryCompat.protocols = protocols.toArray(new String[protocols.size()]);

/* set up reasonable cipher suites */

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {

// choose known secure cipher suites

List allowedCiphers = Arrays.asList(

// TLS 1.2

"TLS_RSA_WITH_AES_256_GCM_SHA384",

"TLS_RSA_WITH_AES_128_GCM_SHA256",

"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",

"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",

"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",

"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",

"TLS_ECHDE_RSA_WITH_AES_128_GCM_SHA256",

// maximum interoperability

"TLS_RSA_WITH_3DES_EDE_CBC_SHA",

"TLS_RSA_WITH_AES_128_CBC_SHA",

// additionally

"TLS_RSA_WITH_AES_256_CBC_SHA",

"TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",

"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",

"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",

"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA");

List availableCiphers = Arrays.asList(socket.getSupportedCipherSuites());

// take all allowed ciphers that are available and put them into preferredCiphers

HashSet preferredCiphers = new HashSet<>(allowedCiphers);

preferredCiphers.retainAll(availableCiphers);

/* For maximum security, preferredCiphers should *replace* enabled ciphers (thus disabling

* ciphers which are enabled by default, but have become unsecure), but I guess for

* the security level of DAVdroid and maximum compatibility, disabling of insecure

* ciphers should be a server-side task */

// add preferred ciphers to enabled ciphers

HashSet enabledCiphers = preferredCiphers;

enabledCiphers.addAll(new HashSet<>(Arrays.asList(socket.getEnabledCipherSuites())));

SSLSocketFactoryCompat.cipherSuites = enabledCiphers.toArray(new String[enabledCiphers.size()]);

}

}

} catch (IOException e) {

throw new RuntimeException(e);

}

}

public SSLSocketFactoryCompat(X509TrustManager tm) {

try {

SSLContext sslContext = SSLContext.getInstance("TLS");

sslContext.init(null, (tm != null) ? new X509TrustManager[] { tm } : null, null);

defaultFactory = sslContext.getSocketFactory();

} catch (GeneralSecurityException e) {

throw new AssertionError(); // The system has no TLS. Just give up.

}

}

private void upgradeTLS(SSLSocket ssl) {

// Android 5.0+ (API level21) provides reasonable default settings

// but it still allows SSLv3

// https://developer.android.com/about/versions/android-5.0-changes.html#ssl

if (protocols != null) {

ssl.setEnabledProtocols(protocols);

}

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP && cipherSuites != null) {

ssl.setEnabledCipherSuites(cipherSuites);

}

}

@Override

public String[] getDefaultCipherSuites() {

return cipherSuites;

}

@Override

public String[] getSupportedCipherSuites() {

return cipherSuites;

}

@Override

public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {

Socket ssl = defaultFactory.createSocket(s, host, port, autoClose);

if (ssl instanceof SSLSocket)

upgradeTLS((SSLSocket)ssl);

return ssl;

}

@Override

public Socket createSocket(String host, int port) throws IOException, UnknownHostException {

Socket ssl = defaultFactory.createSocket(host, port);

if (ssl instanceof SSLSocket)

upgradeTLS((SSLSocket)ssl);

return ssl;

}

@Override

public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {

Socket ssl = defaultFactory.createSocket(host, port, localHost, localPort);

if (ssl instanceof SSLSocket)

upgradeTLS((SSLSocket)ssl);

return ssl;

}

@Override

public Socket createSocket(InetAddress host, int port) throws IOException {

Socket ssl = defaultFactory.createSocket(host, port);

if (ssl instanceof SSLSocket)

upgradeTLS((SSLSocket)ssl);

return ssl;

}

@Override

public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {

Socket ssl = defaultFactory.createSocket(address, port, localAddress, localPort);

if (ssl instanceof SSLSocket)

upgradeTLS((SSLSocket)ssl);

return ssl;

}

}

这样就可以解决了~

不知道如果用别人在OkHttp基础上封装好的工具类,比如okhttp-utils还会不会有这个问题,不过我在使用OkHttp之前,是用AsyncHttpClient做网络库的,因为它已经太老而过时所以换到了OkHttp,在使用AsyncHttpClient的时候也遇到了这个问题

android4.4 ssl版本查看,OkHttp在4.4及以下不支持TLS协议的解决方法相关推荐

  1. android4.4 ssl版本查看,在Android 4.4中启用TLS 1.2

    我使用Retrofit和OkHttp3来发出请求.我知道在 Android 4.4 TLS 1.1和TLS 1.2中没有启用defult.所以我想尝试启用它们.但到目前为止,我没有成功.我读到这可能是 ...

  2. 在命令行窗口查看Maven版本时,出现 Error: JAVA_HOME is set to an invalid directory.的解决方法

    在命令行窗口查看Maven版本时,出现 Error: JAVA_HOME is set to an invalid directory.的解决方法 参考文章: (1)在命令行窗口查看Maven版本时, ...

  3. HTTPS SSL/TLS问题及解决方法汇总

    之前处理过很多ThreadX平台及安卓平台上的SSL问题. SSL问题几乎都和握手失败有关,大致分为四种: 1.客户端没有与服务器相匹配的加密套件,以及SSL版本不匹配. 2.SSL证书错误. 3.网 ...

  4. Windows IIS注册asp 此操作系统版本不支持此选项 错误解决方法

    Windows IIS注册asp 此操作系统版本不支持此选项 错误解决方法 参考文章: (1)Windows IIS注册asp 此操作系统版本不支持此选项 错误解决方法 (2)https://www. ...

  5. 【转】Windows IIS注册asp 此操作系统版本不支持此选项 错误解决方法

    [转]Windows IIS注册asp 此操作系统版本不支持此选项 错误解决方法 参考文章: (1)[转]Windows IIS注册asp 此操作系统版本不支持此选项 错误解决方法 (2)https: ...

  6. 铭瑄H610itx升级E1.4G版本BIOS后HDMI不能输出音频(无HD audio选项)解决方法

    铭瑄H610itx升级E1.4G版本BIOS后HDMI不能输出音频(无HD audio选项)解决方法 1.下载BIOS修改工具 AMIBCP 5.02.0034(其他版本也可以) 2. 修改BIOS设 ...

  7. WebSphere SSLC0008E 无法初始化 SSL 连接。未授权访问被拒绝,或者安全性设置已到期 解决方法

    WebSphere SSLC0008E 无法初始化 SSL 连接.未授权访问被拒绝,或者安全性设置已到期 解决方法 参考文章: (1)WebSphere SSLC0008E 无法初始化 SSL 连接. ...

  8. win7如何看计算机用户名和密码怎么办,win7系统电脑查看共享文件夹时不显示用户名和密码输入窗口的解决方法...

    win7系统使用久了,好多网友反馈说win7系统电脑查看共享文件夹时不显示用户名和密码输入窗口的问题,非常不方便.有什么办法可以永久解决win7系统电脑查看共享文件夹时不显示用户名和密码输入窗口的问题 ...

  9. 华为备份历史版本_华为手机NAS备份时提示“需处于同一局域网”的解决方法

    本内容来源于@什么值得买APP,观点仅代表作者本人 |作者:噩梦飘雷 创作立场声明:在使用华为手机向群晖NAS中备份时发现一直无法成功,经过一番研究找到了解决方案,希望能帮到大家~ 前言 最近看了一位 ...

最新文章

  1. c语言最小费用流_策略算法工程师之路-图优化算法(一)(二分图amp;最小费用最大流)...
  2. 制作嵌入式根文件系统(常见问题详解)
  3. 扩展webupload插件,增加ui界面
  4. CTO不写代码就算了,架构师也不写?
  5. 2020年数学与计算机科学奖获得者,2020 数学与计算机科学奖 获奖人 —— 彭实戈 - 未来科学大奖...
  6. 文件上传漏洞——upload-labs(11-20)
  7. 简单试用了一下 dynamips 7200路由模拟器
  8. java 指令重拍_我发现我的Java重拍了!
  9. 【浅谈DOM事件的优化】
  10. 使用【Linux操作系统】必须掌握的基本命令
  11. 如何在Linux下用C/C++语言操作数据库sqlite3(很不错!设计编译链接等很多问题!)...
  12. 图像处理工程师笔试题
  13. oracle数据库top用法,Oracle TOP SQLHIT
  14. Python操作SQLServer示例
  15. C++ traits学习笔记(一)
  16. 实例讲解统计学基础知识(1):统计学基础概念
  17. java pojo属性,java中的POJO类属性建议使用包装数据类型
  18. Java实现的中间库
  19. java 区分大小写_Java区分大小写
  20. 用学校邮箱使用微软OneDrive云存储空间5120G

热门文章

  1. LOGO设计没有灵感?5种方法来寻找标志设计的灵感和想法
  2. 创意促销海报设计思路,年底忙的设计师来看!
  3. 暗黑模式盛行,如何设计更好的深色UI ?暗黑模式盛行,如何设计更好的深色UI ?
  4. linux sftp ssh端口分开,sftp ssh服务分离
  5. python绘制条形图 中文横坐标_Pyhon绘制数据范围条形图
  6. sql 分组求和_《从零学会SQL-第七关高级功能》课后练习
  7. CUDA的线程层次结构
  8. Linux内存管理:内存寻址之分段机制与分页机制
  9. Linux文件系统之:通用块处理层 ll_rw_block | +往期文章回顾
  10. OpenLTE 基站相关头文件:PHY、MAC、RLC、RRC、PDCP、RB、MME、HSS、GW