【问题标题】:OkHttp SSLHandshakeException SSL handshake aborted Failure in SSL library, a protocol errorOkHttp SSLHandshakeException SSL 握手中止 SSL 库失败,协议错误
【发布时间】:2018-10-03 11:09:59
【问题描述】:
04-23 17:17:38.434 21599-21956/ D/NativeCrypto: ssl=0x0 NativeCrypto_SSL_interrupt
04-23 17:17:38.435 21599-21956/ D/OkHttp: <-- HTTP FAILED: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x635d8808: 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:744 0x5e6c46fd:0x00000000)

Android 低版本设备 (4.1 - 4.4) 出现 SSL 错误。以前使用以下版本可以正常工作:

implementation 'com.squareup.okhttp3:okhttp:3.9.1'
implementation 'com.squareup.okhttp3:okhttp-urlconnection:3.9.1'
implementation 'com.squareup.okhttp3:logging-interceptor:3.9.1'

implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-jackson:2.3.0'
implementation 'com.squareup.retrofit2:adapter-rxjava:2.3.0'

但是在升级这些库之后,情况发生了变化。每个服务调用都会产生 SSL 握手异常。

implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.squareup.okhttp3:okhttp-urlconnection:3.10.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'

implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-jackson:2.4.0'
implementation 'com.squareup.retrofit2:adapter-rxjava:2.4.0'

此外,如果我将这些库降级到以前的版本,它仍然无法工作。但是 git checkout 到上一个提交工作正常。毫无头绪。

【问题讨论】:

  • 您是否在密钥库中添加了证书?
  • @Lucifer 我想我没有。你指的是哪个证书?
  • 你使用的是SSL,所以服务器端应该有一个安全证书。
  • 服务器甚至没有被调用。服务在 android 端被阻止
  • 您应该将其添加为答案,而不是更新您的问题。这样,它将帮助未来的访问者。

标签: android retrofit retrofit2 okhttp okhttp3


【解决方案1】:

所以我通过将以下内容添加到我的 http 客户端对象来解决它

 ConnectionSpec spec = new 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();

httpClient.connectionSpecs(Collections.singletonList(spec))

参考:https://github.com/square/okhttp/issues/3894

【讨论】:

  • 但是如何使用该解决方案与证书固定
  • 我的“客户端未启用 CLEARTEXT 通信”,但在较新的 android 版本上已经有了解决方案。
  • 要了解您的服务器支持哪些 TLS 版本和密码套件,首先使用任何 SSL 分析器(即sslanalyzer.comodoca.com)进行分析,然后相应地更新您的 ConnectionSpec 代码。
  • 我在 AppGlideModule 上遇到了这个问题,无法下载图像并出现以下错误:javax.net.ssl.SSLHandshakeException: Handshake failed
【解决方案2】:

我在升级到 OkHttp 4.x 时遇到了这个问题。不必像 Anker recommends 那样跟踪所有已知的 TLS 版本和所有已知密码,而是使用 OkHttp 的 allEnabledTlsVersionsallEnabledCipherSuites 方法:

val builder = OkHttpClient.Builder()
…
// The default OkHttp configuration does not support older versions of TLS,
// or all cipher suites.  Make our support as reasonably broad as possible.
builder.connectionSpecs(listOf(ConnectionSpec.CLEARTEXT,
    ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
        .allEnabledTlsVersions()
        .allEnabledCipherSuites()
        .build()))
…
val okHttpClient = builder.build()

只要您定期升级 OkHttp,这些列表就会保持最新状态。来自ConnectionSpec API doc

使用 Builder.allEnabledTlsVersions 和 Builder.allEnabledCipherSuites 将所有功能选择推迟到底层 SSL 套接字。

每个规范的配置随着每个 OkHttp 版本的变化而变化。这 很烦人:升级 OkHttp 库可能会中断与 某些网络服务器!但这是一个必要的烦恼,因为 TLS 生态系统是动态的,保持最新是必要的 安全的。请参阅 OkHttp 的 TLS 配置历史记录以跟踪这些更改。

【讨论】:

    猜你喜欢
    • 2018-09-05
    • 2018-07-10
    • 1970-01-01
    • 2021-06-14
    • 2015-07-07
    • 1970-01-01
    • 2014-01-14
    • 1970-01-01
    • 2016-10-19
    相关资源
    最近更新 更多