【问题标题】:Let's Encrypt + Hitch: Android OkHttp java.security.cert.CertPathValidatorException: Response is unreliable: its validity interval is out-of-dateLet's Encrypt + Hitch: Android OkHttp java.security.cert.CertPathValidatorException: Response is unreliable: its valid interval is out-of-date
【发布时间】:2020-08-04 18:24:53
【问题描述】:

您好,感谢您的帮助!

在我们的 Android 应用程序上很少出现以 java.security.cert.CertificateException: Chain validation failed 开头的错误,然后跟踪到 Response is unreliable: its有效性异常间隔已过期。这会影响 API 调用和媒体播放(因为 ExoPlayer 2 使用 okhttp)。

我们通过 Hitch 管理 SSL 交易,并从 Let's Encrypt 获取我们的证书。奇怪的是,当这个问题发生时,证书在 web、iOS tvOS 和 Roku 上仍然可以正常工作,但在 Android 上却不行。

错误是间歇性的,在 24-48 小时内,似乎不再发生此异常。在 okhttp 上,我看到 StackOverflow 文章,其中用户建议将自定义 TrustManager 类添加到接受所有证书的 okhttp 中,但我认为这是不安全的。

我的问题是如何正确记录它接收的有效间隔与预期的有效间隔,以及如何调整 Java 级别的设置以信任超出该窗口的时间,以免发生此异常?

对于上下文,这里是影响播放的堆栈跟踪。


2019-10-21 16:42:51.883 31064-32727/com.sbs.lamusica.debug E/ExoPlayerImplInternal: Source error.
    com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: Unable to connect to https://interstitials.lamusica.com/lamusica/black-video.mp4
        at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:194)
        at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:147)
        at com.google.android.exoplayer2.source.ExtractorMediaPeriod$ExtractingLoadable.load(ExtractorMediaPeriod.java:841)
        at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:308)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)
     Caused by: javax.net.ssl.SSLHandshakeException: Chain validation failed
        at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:236)
        at com.android.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:1480)
        at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:1424)
        at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:1368)
        at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:219)
        at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:142)
        at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:104)
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:392)
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:325)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:470)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
        at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:89)
        at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:26)
        at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:429)
        at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:350)
        at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:192)
        at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:147) 
        at com.google.android.exoplayer2.source.ExtractorMediaPeriod$ExtractingLoadable.load(ExtractorMediaPeriod.java:841) 
        at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:308) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
        at java.lang.Thread.run(Thread.java:764) 
     Caused by: java.security.cert.CertificateException: Chain validation failed
        at com.android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:719)
        at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:543)
        at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:564)
        at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:632)
        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:208)
        at com.android.org.conscrypt.ConscryptFileDescriptorSocket.verifyCertificateChain(ConscryptFileDescriptorSocket.java:426)
        at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
        at com.android.org.conscrypt.NativeSsl.doHandshake(NativeSsl.java:383)
        at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:231)
        at com.android.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:1480) 
        at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:1424) 
        at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:1368) 
        at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:219) 
        at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:142) 
        at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:104) 
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:392) 
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:325) 
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:470) 
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127) 
        at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:89) 
        at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:26) 
        at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:429) 
        at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:350) 
        at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:192) 
        at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:147) 
        at com.google.android.exoplayer2.source.ExtractorMediaPeriod$ExtractingLoadable.load(ExtractorMediaPeriod.java:841) 
        at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:308) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
        at java.lang.Thread.run(Thread.java:764) 
     Caused by: java.security.cert.CertPathValidatorException: Response is unreliable: its validity interval is out-of-date
2019-10-21 16:42:51.886 31064-32727/com.sbs.lamusica.debug E/ExoPlayerImplInternal:     at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135)
        at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:222)
        at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:140)
        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:715)
            ... 34 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)
            ... 40 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)

这是另一个影响 API 调用的堆栈跟踪示例。

javax.net.ssl.SSLHandshakeException: Chain validation failed
    at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:236)
    at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:320)
    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: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:94)
    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:125)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:264)
    at okhttp3.RealCall.execute(RealCall.java:93)
    at com.sbs.lamusica.ui.fragment.home.HomePagerFragment.run(HomePagerFragment.java:200)
    at com.sbs.lamusica.ui.fragment.home.HomePagerFragment$FetchLocationsList.doInBackground(HomePagerFragment.java:706)
    at com.sbs.lamusica.ui.fragment.home.HomePagerFragment$FetchLocationsList.doInBackground(HomePagerFragment.java:693)
    at android.os.AsyncTask$2.call(AsyncTask.java:333)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:764)
Caused by: java.security.cert.CertificateException: Chain validation failed
    at com.android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:719)
    at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:543)
    at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:564)
    at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:632)
    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:208)
    at com.android.org.conscrypt.ConscryptFileDescriptorSocket.verifyCertificateChain(ConscryptFileDescriptorSocket.java:426)
    at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
    at com.android.org.conscrypt.NativeSsl.doHandshake(NativeSsl.java:383)
    at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:231)
    ... 28 more
Caused by: java.security.cert.CertPathValidatorException: Response is unreliable: its validity interval is out-of-date
    at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135)
    at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:222)
    at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:140)
    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:715)
    ... 41 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)
    ... 47 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)
        ... 49 more
2019-07-24 23:45:18.793 1473-3146/? V/WindowManager: Relayout Window{87d24e5 u0 com.sbs.lamusica.deb

【问题讨论】:

标签: java android ssl okhttp exoplayer2.x


【解决方案1】:

感谢大家的帮助!

找了无数遍,终于知道hitch actually automatically manages the retrieval of OCSP staples and it can be configured to attach them了。

在我们的应用程序在这个淫秽时刻再次出现此问题后,我在我的 RedHat 服务器上应用了以下更改:

  1. 创建/var/lib/hitch-ocsp目录
  2. /var/lib/hitch-ocsp的所有权设置为hitch用户
  3. /etc/hitch/hitch.conf 中添加了以下两个选项
ocsp-dir = "/var/lib/hitch-ocsp"
ocsp-verify-staple = on
  1. 运行service hitch restart 重新运行hitch,现在每当我针对https://entrust.ssllabs.com/analyze.html 运行它时,我开始看到OCSP 装订在我的SSL 响应中

到目前为止,我现在看到我们的 Android 应用在更改后立即正确信任这些请求,但如果问题再次出现,我会在此处发布。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-09
    • 2018-01-11
    • 2021-05-07
    • 1970-01-01
    • 2021-10-18
    • 2021-03-30
    • 2022-12-02
    • 1970-01-01
    相关资源
    最近更新 更多