HTTP 失败:javax.net.ssl.SSLHandshakeException:链验证失败

问题描述

我尝试使用 OkHttp 客户端调用 API,但在 Android 中没有成功。 API 在 iOS 和 Postman 上运行良好。

我只在 Android 中获得 SSLHandshakeException。那么,到底是什么原因,又该如何解决呢?

OkHttp 库

implementation 'com.squareup.okhttp3:okhttp:3.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'

Http 客户端

HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
if (BuildConfig.DEBUG)
    builder.addInterceptor(logging);
OkHttpClient client= builder.build();

日志:

javax.net.ssl.SSLHandshakeException: Chain validation Failed
    at com.android.org.conscrypt.SSLUtils.toSSLHandshakeException(SSLUtils.java:362)
    at com.android.org.conscrypt.ConscryptEngine.convertException(ConscryptEngine.java:1134)
    at com.android.org.conscrypt.ConscryptEngine.readplaintextData(ConscryptEngine.java:1089)
    at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:876)
    at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:747)
    at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:712)
    at com.android.org.conscrypt.ConscryptEnginesocket$SSLInputStream.processDataFromSocket(ConscryptEnginesocket.java:849)
    at com.android.org.conscrypt.ConscryptEnginesocket$SSLInputStream.access$100(ConscryptEnginesocket.java:722)
    at com.android.org.conscrypt.ConscryptEnginesocket.doHandshake(ConscryptEnginesocket.java:238)
    at com.android.org.conscrypt.ConscryptEnginesocket.startHandshake(ConscryptEnginesocket.java:217)
    at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:299)
    at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:268)
    at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:160)
    at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:256)
    at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:134)
    at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:113)
    at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)

经过测试的设备和操作系统版本

  1. 一加 6T (Android 10)
  2. 三星 s5(Android 9)
  3. 三星 A5(安卓 6)
  4. Android 模拟器 (Android 11)
  5. LG Nexus(安卓 6)

解决方法

这是 Android Emulator "Chain Validation Failed" connecting developers machine with self-signed certSSLHandshakeException - Chain chain validation failed,how to solve?

的副本

很可能是设备上的日期错误、证书过期(如果它在其他地方工作,则不太可能)或您的 Android 设备上缺少 CA 证书。

如果没有根案例,很难说出发生了什么。您可能只包含了一半的异常跟踪。我相信原因也有关联。

    /**
     * Wraps the given exception if it's not already a {@link SSLHandshakeException}.
     */
    static SSLHandshakeException toSSLHandshakeException(Throwable e) {
        if (e instanceof SSLHandshakeException) {
            return (SSLHandshakeException) e;
        }

        return (SSLHandshakeException) new SSLHandshakeException(e.getMessage()).initCause(e);
    }