Android KitKat 不支持 TLSv1.2

标签 android retrofit2 okhttp tls1.2

我正在旧设备上测试我的应用程序,因为我们的目标是发展中市场,并希望用户拥有旧的、 Lollipop 之前的设备。

我用 RetroFit (2.6.4)OkHttp (3.12.4)与托管在 Amazon 上的 REST 服务器进行通信。 AWS 支持 TLS 1.0、1.1 和 1.2,但我们在 NodeJS 中将其锁定为 TLSv1.2。服务器。

该应用程序适用于新设备,但我在 KitKat 上收到以下错误:

<-- HTTP FAILED: java.net.UnknownServiceException: Unable to find acceptable protocols. isFallback=false, modes=[ConnectionSpec(cipherSuites=[TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256, TLS_AES_128_CCM_SHA256, TLS_AES_256_CCM_8_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256], tlsVersions=[TLS_1_3, TLS_1_2], supportsTlsExtensions=true)], supported protocols=[SSLv3, TLSv1, TLSv1.2]

如果您查看该错误消息的末尾,它会显示:
, tlsVersions=[TLS_1_3, TLS_1_2], supportsTlsExtensions=true)], supported protocols=[SSLv3, TLSv1, TLSv1.2]

所以我认为我有正确的代码来启用 TLSv1.2,但我没有正确使用它,并且 OKHttp 正在尝试使用 SSLv3 或 TLS1 而不是 TLSv1.2。

另外,我刚刚在 SSLLabs 上检查了我们的服务器,它支持以下 TLSv1.2 密码套件:
# TLS 1.2 (suites in server-preferred order)
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)   ECDH secp256r1 (eq. 3072 bits RSA)   FS    128
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)   ECDH secp256r1 (eq. 3072 bits RSA)   FS   WEAK 128
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)   ECDH secp256r1 (eq. 3072 bits RSA)   FS   WEAK    128
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)   ECDH secp256r1 (eq. 3072 bits RSA)   FS    256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)   ECDH secp256r1 (eq. 3072 bits RSA)   FS   WEAK 256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)   ECDH secp256r1 (eq. 3072 bits RSA)   FS   WEAK    256
TLS_RSA_WITH_AES_128_GCM_SHA256 (0x9c)   WEAK   128
TLS_RSA_WITH_AES_128_CBC_SHA256 (0x3c)   WEAK   128
TLS_RSA_WITH_AES_128_CBC_SHA (0x2f)   WEAK  128
TLS_RSA_WITH_AES_256_GCM_SHA384 (0x9d)   WEAK   256
TLS_RSA_WITH_AES_256_CBC_SHA256 (0x3d)   WEAK   256
TLS_RSA_WITH_AES_256_CBC_SHA (0x35)   WEAK  256

完整的堆栈跟踪:
java.net.UnknownServiceException: Unable to find acceptable protocols. isFallback=false, modes=[ConnectionSpec(cipherSuites=[TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256, TLS_AES_128_CCM_SHA256, TLS_AES_256_CCM_8_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256], tlsVersions=[TLS_1_3, TLS_1_2], supportsTlsExtensions=true)], supported protocols=[SSLv3, TLSv1, TLSv1.2]
    at okhttp3.internal.connection.ConnectionSpecSelector.configureSecureSocket(ConnectionSpecSelector.java:74)
    at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:313)
    at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:284)
    at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:169)
    at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:258)
    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:127)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
    at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:225)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:250)
    at okhttp3.RealCall.execute(RealCall.java:93)
    at retrofit2.OkHttpCall.execute(OkHttpCall.java:188)
    at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall.execute(DefaultCallAdapterFactory.java:104)

我正在使用在此博客文章中找到的自定义 SocketFactory:
https://ankushg.com/posts/tls-1.2-on-android/

并像这样使用它:
fun getHttpClientBuilder(enableLogging: Boolean = BuildConfig.DEBUG, vararg customInterceptors: Interceptor): OkHttpClient.Builder {
    val timeoutSecs = if (BuildConfig.DEBUG) 0 else TIMEOUT_SECONDS_RELEASE
    val httpClientBuilder = OkHttpClient.Builder()
        .connectTimeout(timeoutSecs.toLong(), TimeUnit.SECONDS)
        .readTimeout(timeoutSecs.toLong(), TimeUnit.SECONDS)
        .writeTimeout(timeoutSecs.toLong(), TimeUnit.SECONDS)
        .connectionSpecs(listOf(ConnectionSpec.RESTRICTED_TLS)) //  Restrict to TLS 1.2 and 1.3

    for (customInterceptor in customInterceptors) {
        httpClientBuilder.addInterceptor(customInterceptor)
    }

    val logger = HttpLoggingInterceptor()
    logger.level = if (enableLogging) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.BASIC
    httpClientBuilder.addInterceptor(logger)

    return httpClientBuilder
}

fun buildHttpClient(enableLogging: Boolean = BuildConfig.DEBUG, vararg customInterceptors: Interceptor): OkHttpClient {
    return getHttpClientBuilder(enableLogging, *customInterceptors)
        .enableTls12() //This calls the custom socket factory
        .build()
}
enableTls12()函数调用触发此代码:
  @JvmStatic
    fun OkHttpClient.Builder.enableTls12() = apply {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
            try {
                val sslContext = SSLContext.getInstance(TlsVersion.TLS_1_2.javaName())
                sslContext.init(null, arrayOf(trustManager), null)

                sslSocketFactory(Tls12SocketFactory(sslContext.socketFactory), trustManager)
            } catch (e: Exception) {
                println("Error while setting TLS 1.2 compatibility:: ${e.localizedMessage}")
            }
        }
    }

所以我想我有我需要的一切,这应该可以工作。
有人对我可以尝试什么或我缺少什么有任何建议吗?

谢谢

最佳答案

与以下链接类似的问题,检查 Tls12SocketFactory 实现 Android 4.1 to 4.4 KitKat - Enable TLS 1.2 for API

关于Android KitKat 不支持 TLSv1.2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60970805/

相关文章:

java - 为什么异步网络调用的回调方法在Activity结束时不会造成内存泄漏?

android - 如何将数据从 okhttp 和 Asynctask 放入 RecyclerView

java - 如何点击包含冒号的 Retrofit URL (:)?

android - 无法弄清楚在 OkHttp 的 onResponse 方法中要检查什么

android - 我还能在明年 2019 年使用 gradle 插件 2.30 吗?

Android:毫米或英寸尺寸的 View 尺寸不正确

android - 为什么不显示 Leadbolt 图标广告?

javascript - 在 Cocos2d-JS 中使用 Google Play 服务

android - 启用 Proguard 时 Retrofit2 不工作

android - 类型不匹配 : inferred type is <no name provided> but Callback<Post! >!预计