【问题标题】:TrustManagerFactory - Ignore certificate checkTrustManagerFactory - 忽略证书检查
【发布时间】:2020-03-04 22:10:47
【问题描述】:

我正在使用一个库来连接到 Azure,它使用 okhttp3 来处理连接。 这个库中有一部分调用了 okhttp3.internal.Util#platformTrustManager

 public static X509TrustManager platformTrustManager() {
        try {
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init((KeyStore)null);
            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
            if (trustManagers.length == 1 && trustManagers[0] instanceof X509TrustManager) {
                return (X509TrustManager)trustManagers[0];
            } else {
                throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
            }
        } catch (GeneralSecurityException var2) {
            throw assertionError("No System TLS", var2);
        }
    }

还有javax.net.ssl.TrustManagerFactory#getInstance(java.lang.String)

public static final TrustManagerFactory getInstance(String var0) throws NoSuchAlgorithmException {
        Instance var1 = GetInstance.getInstance("TrustManagerFactory", TrustManagerFactorySpi.class, var0);
        return new TrustManagerFactory((TrustManagerFactorySpi)var1.impl, var1.provider, var0);
    }

由于某种原因,我收到 javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certificate path到请求的目标

Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1639)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
    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: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 com.microsoft.rest.retry.RetryHandler.intercept(RetryHandler.java:75)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
    at com.microsoft.rest.interceptors.CustomHeadersInterceptor.intercept(CustomHeadersInterceptor.java:140)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
    at com.microsoft.rest.interceptors.UserAgentInterceptor.intercept(UserAgentInterceptor.java:83)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
    at com.microsoft.azure.credentials.AzureTokenCredentialsInterceptor.intercept(AzureTokenCredentialsInterceptor.java:40)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
    at com.microsoft.azure.management.resources.fluentcore.utils.ResourceManagerThrottlingInterceptor.intercept(ResourceManagerThrottlingInterceptor.java:54)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
    at com.microsoft.azure.management.resources.fluentcore.utils.ProviderRegistrationInterceptor.intercept(ProviderRegistrationInterceptor.java:40)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
    at com.microsoft.rest.interceptors.BaseUrlHandler.intercept(BaseUrlHandler.java:43)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
    at com.microsoft.rest.interceptors.RequestIdHeaderInterceptor.intercept(RequestIdHeaderInterceptor.java:29)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:257)
    at okhttp3.RealCall.execute(RealCall.java:93)
    at retrofit2.OkHttpCall.execute(OkHttpCall.java:186)
    at retrofit2.adapter.rxjava.CallExecuteOnSubscribe.call(CallExecuteOnSubscribe.java:40)
    at retrofit2.adapter.rxjava.CallExecuteOnSubscribe.call(CallExecuteOnSubscribe.java:24)
    at rx.Observable.unsafeSubscribe(Observable.java:10327)
    at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:48)
    at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:33)
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
    at rx.Observable.subscribe(Observable.java:10423)
    at rx.Observable.subscribe(Observable.java:10390)
    at rx.observables.BlockingObservable.blockForSingle(BlockingObservable.java:443)
    ... 35 more

证书在 sun.security.ssl.ClientHandshaker#serverCertificate 进行验证:

 ((X509ExtendedTrustManager)var6).checkServerTrusted((X509Certificate[])var2.clone(), var4, this.conn);

这是一个真正有效的证书,但错误仍然存​​在。

我不确定如何解决这个问题。我想完全禁用证书验证,但我似乎也找不到在此设置中执行此操作的方法。

为什么一个有效的证书会抛出这个错误?

如何“安装”此证书(我只能通过调试以文本形式获取),或禁用验证?

另外,我在 Windows 上运行它。

【问题讨论】:

  • 您如何将证书传递给代码进行验证?
  • 我不是。我的意思是,trustManagerFactory.init((KeyStore)null);从某个地方加载 94 个证书,但我相信它缺少一些东西。
  • docs.oracle.com/en/java/javase/11/security/… 描述了默认的信任库,尤其是第 4 段第 5 段和第 7 段。您可以自己查看文件,也可以通过跟踪docs.oracle.com/en/java/javase/11/security/… 查看正在加载的内容您可以使用keytool -printcert -sslserver $host[:$port] -rfc 获取服务器证书(几乎永远不会只有一个证书)的副本跨度>
  • 所以你可以做几件事。将 Azure 证书包含在 jdk/jre 的 cacert 中。我建议使用keystore explorer 或者您也可以尝试提供一个自定义的 okhttp,您可以使用自定义 sslcontext 对其进行配置。您可以使用以下代码实现: SSLContext sslcontext = ...; OkHttpClient 客户端 = new OkHttpClient.Builder() .sslSocketFactory(sslcontext.getSocketFactory()); .build();
  • 无论您的问题是什么,“我想禁用证书验证”都不是正确的解决方案。这意味着您几乎取消了 TLS 的所有用处,并且您可以使用纯文本。

标签: java azure ssl


【解决方案1】:

Synoli's answer and great explanation 之后,我设法加载了正确的 Windows 证书存储:

System.setProperty("javax.net.ssl.trustStore", "NUL");
System.setProperty("javax.net.ssl.trustStoreType", "Windows-ROOT");

我不确定证书在 Windows 中是如何保存和分离的,但如果没有此修复,会加载很多证书但我需要的证书。

【讨论】:

    猜你喜欢
    • 2021-09-26
    • 2023-03-30
    • 1970-01-01
    • 2019-07-01
    • 2017-06-01
    • 2019-04-18
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多