You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android老版本应用HTTPS登录遇CertificateExpiredException问题求助

问题背景

该错误仅出现在一款2018年左右创建的Android应用中,此前一直正常运行,数月前开始出现异常。错误触发于发起HTTPS POST登录API请求时,指向同一接口的iOS版本应用运行正常。

问题现象

日志显示登录请求已成功,但受该错误影响无法进入登录后的页面;重新创建应用并配置登录组件后,日志显示可正常登录API,说明仅该特定版本应用存在问题。

错误日志
W/System.err: javax.net.ssl.SSLHandshakeException: Chain validation failed
W/System.err:     at com.android.org.conscrypt.SSLUtils.toSSLHandshakeException(SSLUtils.java:362)
W/System.err:     at com.android.org.conscrypt.ConscryptEngine.convertException(ConscryptEngine.java:1134)
W/System.err:     at com.android.org.conscrypt.ConscryptEngine.readPlaintextData(ConscryptEngine.java:1089)
W/System.err:     at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:876)
W/System.err:     at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:747)
W/System.err:     at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:712)
W/System.err:     at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:849)
W/System.err:     at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.access$100(ConscryptEngineSocket.java:722)
W/System.err:     at com.android.org.conscrypt.ConscryptEngineSocket.doHandshake(ConscryptEngineSocket.java:238)
W/System.err:     at com.android.org.conscrypt.ConscryptEngineSocket.startHandshake(ConscryptEngineSocket.java:217)
W/System.err:     at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.kt:379)
W/System.err:     at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.kt:337)
W/System.err:     at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:209)
W/System.err:     at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:226)
W/System.err:     at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:106)
W/System.err:     at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:74)
W/System.err:     at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:255)
W/System.err:     at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
W/System.err:     at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
W/System.err:     at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
W/System.err:     at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
W/System.err:     at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
W/System.err:     at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154)
W/System.err:     at retrofit2.OkHttpCall.execute(OkHttpCall.java:188)
W/System.err:     at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:45)
W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:12267)
W/System.err:     at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:12267)
W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFromObservable.subscribeActual(FlowableFromObservable.java:29)
W/System.err:     at io.reactivex.Flowable.subscribe(Flowable.java:14918)
W/System.err:     at io.reactivex.internal.operators.flowable.FlowableOnBackpressureLatest.subscribeActual(FlowableOnBackpressureLatest.java:32)
W/System.err:     at io.reactivex.Flowable.subscribe(Flowable.java:14918)
W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFlatMap.subscribeActual(FlowableFlatMap.java:53)
W/System.err:     at io.reactivex.Flowable.subscribe(Flowable.java:14918)
W/System.err:     at io.reactivex.internal.operators.flowable.FlowableMap.subscribeActual(FlowableMap.java:37)
W/System.err:     at io.reactivex.Flowable.subscribe(Flowable.java:14918)
W/System.err:     at io.reactivex.Flowable.subscribe(Flowable.java:14865)
W/System.err:     at io.reactivex.internal.operators.flowable.FlowableOnErrorNext$OnErrorNextSubscriber.onError(FlowableOnErrorNext.java:115)
W/System.err:     at io.reactivex.internal.operators.single.SingleToFlowable$SingleToFlowableObserver.onError(SingleToFlowable.java:67)
W/System.err:     at io.reactivex.internal.operators.single.SingleCreate$Emitter.tryOnError(SingleCreate.java:94)
W/System.err:     at io.reactivex.internal.operators.single.SingleCreate$Emitter.onError(SingleCreate.java:80)
W/System.err:     at com.parabit.parabeacon.app.demo.data_section.LocalStorage.lambda$getDeviceIdInfo$15(LocalStorage.java:236)
W/System.err:     at com.parabit.parabeacon.app.demo.data_section.LocalStorage$$ExternalSyntheticLambda9.subscribe(Unknown Source:2)
W/System.err:     at io.reactivex.internal.operators.single.SingleCreate.subscribeActual(SingleCreate.java:39)
W/System.err:     at io.reactivex.Single.subscribe(Single.java:3603)
W/System.err:     at io.reactivex.internal.operators.single.SingleToFlowable.subscribeActual(SingleToFlowable.java:37)
W/System.err:     at io.reactivex.Flowable.subscribe(Flowable.java:14918)
W/System.err:     at io.reactivex.internal.operators.flowable.FlowableOnErrorNext.subscribeActual(FlowableOnErrorNext.java:40)
W/System.err:     at io.reactivex.Flowable.subscribe(Flowable.java:14918)
W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFlatMap.subscribeActual(FlowableFlatMap.java:53)
W/System.err:     at io.reactivex.Flowable.subscribe(Flowable.java:14918)
W/System.err:     at io.reactivex.Flowable.subscribe(Flowable.java:14865)
W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.onNext(FlowableFlatMap.java:163)
W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFromArray$ArraySubscription.slowPath(FlowableFromArray.java:162)
W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFromArray$BaseArraySubscription.request(FlowableFromArray.java:90)
W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.onSubscribe(FlowableFlatMap.java:117)
W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFromArray.subscribeActual(FlowableFromArray.java:38)
W/System.err:     at io.reactivex.Flowable.subscribe(Flowable.java:14918)
W/System.err:     at io.reactivex.internal.operators.flowable.FlowableFlatMap.subscribeActual(FlowableFlatMap.java:53)
W/System.err:     at io.reactivex.Flowable.subscribe(Flowable.java:14918)
W/System.err:     at io.reactivex.Flowable.subscribe(Flowable.java:14865)
W/System.err:     at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
W/System.err:     at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
W/System.err:     at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err:     at java.lang.Thread.run(Thread.java:923)
W/System.err: Caused by: java.security.cert.CertificateException: Chain validation failed
W/System.err:     at com.android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:724)
W/System.err:     at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:554)
W/System.err:     at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:575)
W/System.err:     at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:620)
I/chatty: uid=10207(com.parabit.parabeacon.app.demo) identical 1 line
W/System.err:     at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:620)
W/System.err:     at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:510)
W/System.err:     at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:428)
W/System.err:     at com.android.org.conscrypt.TrustManagerImpl.getTrustedChainForServer(TrustManagerImpl.java:356)
W/System.err:     at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:94)
W/System.err:     at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:90)
W/System.err:     at com.android.org.conscrypt.ConscryptEngineSocket$2.checkServerTrusted(ConscryptEngineSocket.java:161)
W/System.err:     at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:250)
W/System.err:     at com.android.org.conscrypt.ConscryptEngine.verifyCertificateChain(ConscryptEngine.java:1644)
W/System.err:     at com.android.org.conscrypt.NativeCrypto.ENGINE_SSL_read_direct(Native Method)
W/System.err:     at com.android.org.conscrypt.NativeSsl.readDirectByteBuffer(NativeSsl.java:568)
W/System.err:     at com.android.org.conscrypt.ConscryptEngine.readPlaintextDataDirect(ConscryptEngine.java:1095)
W/System.err:     at com.android.org.conscrypt.ConscryptEngine.readPlaintextData(ConscryptEngine.java:1079)
W/System.err:   ... 70 more
W/System.err: Caused by: java.security.cert.CertPathValidatorException: timestamp check failed
W/System.err:     at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135)
W/System.err:     at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:222)
W/System.err:     at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:140)
W/System.err:     at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:79)
W/System.err:     at java.security.cert.CertPathValidator.validate(CertPathValidator.java:301)
W/System.err:     at com.android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:720)
W/System.err:   ... 87 more
W/System.err: Caused by: java.security.cert.CertificateExpiredException: Certificate expired at Thu Oct 20 19:59:59 EDT 2022 (compared to Wed Jan 04 17:53:35 EST 2023) //<- Here's the real issue
W/System.err:     at com.android.org.conscrypt.OpenSSLX509Certificate.checkValidity(OpenSSLX509Certificate.java:269)
W/System.err:     at sun.security.provider.certpath.BasicChecker.verifyTimestamp(BasicChecker.java:194)
W/System.err:     at sun.security.provider.certpath.BasicChecker.check(BasicChecker.java:144)
W/System.err:     at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:125)
W/System.err:   ... 92 more
求助说明

我已搜索一整天但未找到可行解决方案,恳请各位提供思路或解决办法,如需更多信息请告知。

补充:该Android应用基于Android Studio构建。


解决方案

从错误日志根因CertificateExpiredException可明确问题:应用信任的证书链中有证书在2022年10月20日过期,iOS应用正常是因为系统信任的根证书库已自动更新,旧Android应用对应解决办法如下:

1. 替换应用内置的过期证书

如果旧版本应用手动内置了服务器/中间证书(早年为兼容旧Android版本硬编码):

  • 从服务器获取当前有效的完整证书链(含服务器证书、中间证书、根证书)
  • 替换应用中内置的旧证书文件
  • 重新编译打包发布应用

2. 更新网络依赖库版本

旧版OkHttp、Retrofit可能存在证书链处理缺陷,或未兼容新根证书:

  • 将OkHttp升级到最新稳定版(如从旧版本升级至4.x系列)
  • 同步更新Retrofit及相关适配器(如rxjava2适配器)
  • 清理项目缓存后重新构建

3. 配置网络安全策略适配旧系统

Android 8.0以下系统的根证书库未包含新根证书,可通过配置解决:

  • 在res/xml/network_security_config.xml中配置信任当前服务器的证书链
  • 或配置允许同时使用系统与应用内置的证书源

4. 临时排查验证(仅测试环境用)

临时禁用证书验证,确认是否为证书问题(禁止生产环境使用):

// OkHttp配置示例
OkHttpClient client = new OkHttpClient.Builder()
    .sslSocketFactory(new SSLSocketFactoryCompat(), new TrustAllManager())
    .hostnameVerifier((hostname, session) -> true)
    .build();

// 辅助实现类
static class TrustAllManager implements X509TrustManager {
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) {}
    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) {}
    @Override
    public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}
}

内容的提问来源于stack exchange,提问作者OEThe11

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 20:55:37