【问题标题】:SSL connection error on valid certificate有效证书上的 SSL 连接错误
【发布时间】:2019-07-14 02:07:09
【问题描述】:

我得到了一个javax.net.ssl.SSLHandshakeException: Chain validation failed,当我尝试连接到我的 API 服务器时,证书现在有效,在堆栈跟踪中我得到了Caused by: java.security.cert.CertPathValidatorException: Response is unreliable: its validity interval is out-of-date,证书有效并且在 iOS 上运行而在网站上,问题只出在 Android 上。

我正在使用 Retrofit,这是客户端生成

fun generateClient(): OkHttpClient {
        val client = OkHttpClient.Builder()
        client.addInterceptor {
            val request = it.request()
            val url = request.url().newBuilder()
                .build()
            val newRequest = it.request().newBuilder().url(url).build()
            it.proceed(newRequest)
        }
        client.connectTimeout(10, TimeUnit.SECONDS)
        client.readTimeout(30, TimeUnit.SECONDS)
        return client.build()
    }

完整的痕迹是这样的

javax.net.ssl.SSLHandshakeException: Chain validation failed
    at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:361)
    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 es.app.webservice.WebService$Companion$generateClient$1.intercept(WebService.kt:67)
    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.execute(RealCall.java:77)
    at retrofit2.OkHttpCall.execute(OkHttpCall.java:180)
    at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.execute(ExecutorCallAdapterFactory.java:91)
    at es.app.bd.cacheDb.databseRepositories.SplashActivityRepository$getVersions$1.invoke(SplashActivityRepository.kt:28)
    at es.app.bd.cacheDb.databseRepositories.SplashActivityRepository$getVersions$1.invoke(SplashActivityRepository.kt:17)
    at kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30)
 Caused by: java.security.cert.CertificateException: Chain validation failed
    at com.android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:788)
    at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:612)
    at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:633)
    at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:678)
    at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:499)
    at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:422)
    at com.android.org.conscrypt.TrustManagerImpl.getTrustedChainForServer(TrustManagerImpl.java:343)
    at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:94)
    at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:88)
    at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:203)
    at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:607)
    at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
    at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
    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 es.app.bd.cacheDb.webservice.WebService$Companion$generateClient$1.intercept(WebService.kt:67) 
    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.execute(RealCall.java:77) 
    at retrofit2.OkHttpCall.execute(OkHttpCall.java:180) 
    at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.execute(ExecutorCallAdapterFactory.java:91) 
    at es.app.bd.cacheDb.databseRepositories.SplashActivityRepository$getVersions$1.invoke(SplashActivityRepository.kt:28) 
    at es.app.bd.cacheDb.databseRepositories.SplashActivityRepository$getVersions$1.invoke(SplashActivityRepository.kt:17) 
    at kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30) 
 Caused by: java.security.cert.CertPathValidatorException: Response is unreliable: its validity interval is out-of-date
E/AndroidRuntime:     at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:133)
    at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:225)
    at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:143)
    at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:79)
    at com.android.org.conscrypt.DelegatingCertPathValidator.engineValidate(DelegatingCertPathValidator.java:44)
    at java.security.cert.CertPathValidator.validate(CertPathValidator.java:301)
    at com.android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:784)
        ... 39 more
 Caused by: java.security.cert.CertPathValidatorException: Response is unreliable: its validity interval is out-of-date
    at sun.security.provider.certpath.OCSPResponse.verify(OCSPResponse.java:619)
    at sun.security.provider.certpath.RevocationChecker.checkOCSP(RevocationChecker.java:709)
    at sun.security.provider.certpath.RevocationChecker.check(RevocationChecker.java:363)
    at sun.security.provider.certpath.RevocationChecker.check(RevocationChecker.java:337)
    at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:125)
        ... 45 more
    Suppressed: java.security.cert.CertPathValidatorException: Could not determine revocation status
    at sun.security.provider.certpath.RevocationChecker.buildToNewKey(RevocationChecker.java:1092)
    at sun.security.provider.certpath.RevocationChecker.verifyWithSeparateSigningKey(RevocationChecker.java:910)
    at sun.security.provider.certpath.RevocationChecker.checkCRLs(RevocationChecker.java:577)
    at sun.security.provider.certpath.RevocationChecker.checkCRLs(RevocationChecker.java:465)
    at sun.security.provider.certpath.RevocationChecker.check(RevocationChecker.java:394)
            ... 47 more

更新 1: 如果我从手机上的 Chrome 访问网页,它可以工作,但应用程序仍然崩溃。

【问题讨论】:

标签: java android ssl kotlin retrofit2


【解决方案1】:

在我的情况下,只需在设备上设置适当的系统时间(“设置”>“系统”>“日期和时间”>“自动日期和时间”)就足够了。

【讨论】:

    【解决方案2】:

    查看Suppressed: java.security.cert.CertPathValidatorException: Could not determine revocation status 行表明失败发生在依赖于 OCSP 协议的撤销验证步骤。

    这里可能发生的情况是,您的设备未连接到互联网,并且无法联系授权服务器以检查您的证书的有效性(这只是一个猜测)。

    如果您不希望您的应用程序访问授权服务器,您应该在您的服务器上激活“OCSP stappling”。这意味着您的服务器将发送 OCSP 验证回执以及证书。

    【讨论】:

      【解决方案3】:

      就我而言,我不得不将这句话添加到 AndroidManifest.xml:

      android:usesCleartextTraffic="true"
      

      如上下文所示:

      【讨论】:

        猜你喜欢
        • 2017-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-19
        • 1970-01-01
        • 2018-12-18
        • 2015-07-04
        相关资源
        最近更新 更多