Retrofit2 上的 HTTPs SSLProtocolException

2024-02-14

我在 Android 4.4 手机(特别是 Galaxy S4,尽管我相信这不是手机本身的问题)上遇到了问题。使用 Retrofit2.Http 在 HTTPS 连接时收到以下错误:

javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x737510d0: 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 0x727fb7d0:0x00000000)

我发现一些资源表明这是 Android 4.4(1) 上的一个错误,但给出的示例始终假设使用 HttpsUrlConnection 类,而我没有使用该类。

我确实在这里找到了一些关于为连接设置特定 ConnectionSpec 实例的答案,这似乎很有希望,因为它是针对 Retrofit 的(2)。不幸的是,这对错误没有影响。我的代码示例(我尝试了 MODERN_TLS 和 COMPATIBLE_TLS):

return new OkHttpClient.Builder()
                .addInterceptor(interceptor)
                .connectionSpecs(Collections.singletonList(ConnectionSpec.MODERN_TLS))
                .build();

切换到“http”确实有效,但这不是最终版本的选项。安全、加密的连接是绝对必要的,因此任何完全禁用 HTTPS 或盲目接受任何证书的解决方案都不太可能被接受。

提前致谢!

(1) Javax.net.ssl.SSLHandshakeException:javax.net.ssl.SSLProtocolException:SSL 握手中止:SSL 库失败,通常是协议错误 https://stackoverflow.com/questions/29916962/javax-net-ssl-sslhandshakeexception-javax-net-ssl-sslprotocolexception-ssl-han

(2) 改造 OkHttp SSLHandshakeException https://stackoverflow.com/questions/33353251/retrofit-okhttp-sslhandshakeexception

Edit:

运行 openssl 会给出以下结果:

[[my_computer]]$ ./openssl s_client -connect [[server_hidden_by_me]]:443 -tls1


CONNECTED(00000003)
depth=2 /C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/OU=Domain Control Validated/OU=PositiveSSL/CN=[hidden_by_me]
   i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
 1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
   i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
 2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
   i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
---
Server certificate
-----BEGIN CERTIFICATE-----
[snip certificate for brevity]
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/OU=PositiveSSL/CN=[hidden_by_me]
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
---
No client certificate CA names sent
---
SSL handshake has read 5449 bytes and written 426 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-SEED-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-SEED-SHA
    Session-ID: A4D84E2A0A16DB03082172695141BE1BB562F920ED4E4F6A9139733D9CAB7A54
    Session-ID-ctx: 
    Master-Key: 119C10E5CC34297D1717E4AEAB8BF1CAA8BA012C125B10513FBFE0854B6AB0E9E65536F801990CA3C992FEB69ADBE279
    Key-Arg   : None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - 5c 21 2c ac 68 a9 ef 71-8c 69 2a 86 0c da 6c cd   \!,.h..q.i*...l.
    [snipped for brevity]

    Start Time: 1464109807
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---

Nexus 7 (Android 4.4.4) 也有类似问题。发现它尝试通过 TLSv1 进行连接,而我的服务器默认未启用该协议。通过启用它来修复 =)

您可以使用 openssl 测试您的服务器:openssl s_client -connect google.com:443 -tls1

Update:

此代码在我的设备上强制使用 TLSv1,顺便说一句,它仅支持 SSLv3、TLSv1。使用 okhttp:3.3.0 测试

ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
        .tlsVersions(TlsVersion.TLS_1_0)
        .allEnabledCipherSuites()
        .build();

OkHttpClient client = new OkHttpClient.Builder()
        .connectionSpecs(Collections.singletonList(spec))
        .build();

Request request = new Request.Builder()
        .url("https://192.168.0.19:44330")
        .build();

try {
    client.newCall(request).execute();
} catch (IOException e) {
    e.printStackTrace();
}

使用 openssl 服务器查看它真正使用的协议版本,您将需要证书和密钥文件:

openssl s_server -key key.pem -cert cert.cer -accept 44330 -www -msg

希望这可以帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Retrofit2 上的 HTTPs SSLProtocolException 的相关文章

  • 是否可以以编程方式更改操作栏选项卡指示器

    如何以编程方式更改操作栏的选定选项卡指示器 我读过关于选项卡样式 http developer android com guide topics ui actionbar html Style和 Tab setCustomView 方法 但
  • FireStore 日期查询未按预期工作

    我有一个有日期对象的文档 初始化 Firestore 的代码 FirebaseFirestore fireStore FirebaseFirestore getInstance FirebaseFirestoreSettings setti
  • Android spinner 将多列(连接)Sqlite 数据库加载到表中

    我正在学习如何创建一个从 SQLite 加载下拉列表的微调器 我有一个由旋转器和表格组成的用户界面 如果用户单击微调器 表的内容将根据微调器上选定的 ID 根据数据库加载 如果未选择名称 它将加载表中的所有内容 但是我找不到如何根据微调器上
  • 序列化 ArrayList

    我正在尝试编写一个 Android 游戏 即使用户想要返回主菜单或者活动被系统终止 我也希望能够暂停游戏 onSaveInstanceState 似乎并没有给我很大的控制权来决定何时可以读回捆绑包 而且据我所知 捆绑包仅在短时间内有效 所以
  • Android NDK:断言失败:TARGET_PLATFORM 未定义

    使用 NDK r5b 时 当我使用以下命令在 jni 目录中进行构建时 NDK DIR ndk build 效果很好 但是当我切换到 r6b 只需以不同的方式设置 NDK DIR 并运行相同的命令时 我得到 usr local androi
  • 检查 key 是否存在 firebase Android

    我想检查 firebase 数据库中是否存在密钥 例如 我想查找关键的 upvotes 以查看它是否存在 Here is an exmaple upvotes key does not exist in here 现在我尝试检查密钥 upv
  • 即使具有用户权限,也无法在外部存储上保存文件 [Android]

    我正在 Android 上开发一个用于图像处理的应用程序 但我一直在编写图像保存代码 这是我使用的方法 private void saveImageToExternalStorage Bitmap finalBitmap String ro
  • Android studio 3.0不生成签名的apk

    将 android studio 更新到版本 3 0 Windows 后 我无法生成签名的 APK 构建完成后 我收到消息 单击 查找 会将我带到 APP 文件夹 但找不到 APK 改变了什么 自Android Studio 3 0更新后
  • 更新到最新版本(3.1)后缺少 google-play-services_lib.jar

    我在我的应用程序中使用 Google Play 服务已经有一段时间了 没有出现任何问题 我正在使用 Eclipse 我已在 I O 后将播放服务 以及 ADT 和 SDK 更新到最新版本 但现在我无法构建我的应用程序 我已将 google
  • Android Cloud 2 设备消息传递 (C2DM) 是否与 Google 的两步验证兼容?

    我一直在阅读 Android 的云 2 设备消息传递 C2DM 所有文档都提到 ClientLogin 作为身份验证方法 但是 那客户端登录 http code google com apis accounts docs AuthForIn
  • 如何使用Gson将JSONArray转换为List?

    在我的 Android 项目中 我试图将收到的 JSONArray 转换为列表 在 的帮助下这个答案 https stackoverflow com questions 8371274 how to parse json array in
  • 在 Cordova / PhoneGap 中生成 iOS 和 Android 图标

    我有一个新创建的 Cordova 项目 其中包含以下内容config xml设置 使用来自http docs phonegap com en edge config ref images md html http docs phonegap
  • 如何更改Android软键盘中任意键的按键背景

    我想让键盘上的一些键与其他键不同 例如下图中的shift 删除 空格键 根据google的参考文档 我们可以通过使用 来改变按键的背景android keybackground drawable xxx in input xml 但它改变了
  • ListPreferences 的异常

    这是我的第一个 Android 应用程序 在尝试使用 ListPreference 时遇到了异常 应用程序与首选项一起加载 但是当我触摸 ListPreference 条目时 应用程序 意外停止 设置 java public class S
  • 为什么 Internet Explorer 无法使用 NodeJS 和 Express 下载 PDF?

    我正在使用 NodeJS 构建一个网站 需要提供一些 PDF 以及其他文件 由于我无法确定的原因 Internet Explorer 8 第一次无法在 Acrobat Viewer 中完全下载 PDF 有时此后多次 直接保存文件效果很好 但
  • 如何在Android手机上而不是模拟器上运行或调试?

    Android 模拟器速度太慢 无法测试运行的应用程序 有没有办法使用 IDE 而不是模拟器在真实手机上调试 运行应用程序 通常 您可以在手机上打开 USB 调试 然后通过 USB 将其连接到 PC 然后 手机将以与模拟器相同的方式出现在
  • getApplicationDocumentsDirectory 在 flutter 桌面(Windows)上不起作用

    如何在 Windows 上的 flutter 桌面上保存和打开文件 getApplicationDocumentsDirectory 不适用于 Windows 应用程序的 flutter 桌面 Future
  • 如何从 Android 应用程序调用 REST API? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我是 android 新手 也是编程新手 如何从 Android 应用程序调用 REST api GET POST 请求 请给我推荐一
  • 更改 ActionMode 溢出图标

    有没有办法更改 ActionMode Overflow 图标而不更改 正常 ActionBar 的图标 我仍然需要弄清楚如何仅更改 ActionMode Actionbar 内部的溢出图标 因为我更改了默认操作栏中的溢出图标 该图标在 Ac
  • Android NDK - 仅用 C/C++ 编写

    有没有一种可能的方法可以使用 C C 编写整个 NDK 应用程序 而无需像 hello jni 示例项目 HelloJni java 中那样的 Java 入门 类 以某种方式创建一个 HelloJni c 来执行相同的操作 从 Androi

随机推荐