当前位置: 首页 > 知识库问答 >
问题:

nginx - 证书链完整,okhttp3请求错误?

董宜然
2024-09-19

证书情况

myssl.com验证证书是正常的
https://myssl.com/ynslyszx.com

浏览器中查看

image.png

使用命令查看

image.png

测试代码

public static void main(String[] args) {

        String url = "https://ynslyszx.com/fp04/ldt-service/msp/getPublicKey.do";
        OkHttpClient client = new OkHttpClient();
        // 指定你要请求的URL
        Request request = new Request.Builder()
                .url(url)
                .build();
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code " + response);
            }
            // 打印响应体的内容
            System.out.println(response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

错误信息

使用okhttp请求报错:

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.Alert.createSSLException(Alert.java:131)
    at sun.security.ssl.TransportContext.fatal(TransportContext.java:353)
    at sun.security.ssl.TransportContext.fatal(TransportContext.java:296)
    at sun.security.ssl.TransportContext.fatal(TransportContext.java:291)
    at sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:652)
    at sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:471)
    at sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:367)
    at sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:376)
    at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)
    at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:422)
    at sun.security.ssl.TransportContext.dispatch(TransportContext.java:183)
    at sun.security.ssl.SSLTransport.decode(SSLTransport.java:154)
    at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1279)
    at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1188)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:401)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:373)
    at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.kt:379)
    at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.kt:337)
    at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:209)
    at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:226)
    at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:106)
    at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:74)
    at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:255)
    at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
    at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154)
    at org.example.App.main(App.java:35)
Caused by: 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.validator.PKIXValidator.doBuild(PKIXValidator.java:439)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306)
    at sun.security.validator.Validator.validate(Validator.java:271)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:312)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:221)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:128)
    at sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:636)
    ... 29 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:434)
    ... 35 more

问题

  1. 同样的代码,请求https://baidu.com或https://qq.com是正常的,请求ynslyszx.com就出错;使用myssl.com验证后,证书也是正常的,请问是哪个环节出错?
  2. 服务器中尝试用myssl.com修复过证书,也是请求不通。
  3. 目前解决办法是使okhttp3忽略全部证书验证,但是这样不太合适,请问是否有其他解决方案?

共有2个答案

金嘉
2024-09-19

java的信任ca是自己私有的。不跟操作系统的混一起。cfca的ca证书不被信任。手动信任就行了。

linux的话手动执行一下update-ca-trust试试看 (rhel)

满言
2024-09-19

问题解答

  1. 同样的代码,请求https://baidu.com或https://qq.com是正常的,请求ynslyszx.com就出错;使用myssl.com验证后,证书也是正常的,请问是哪个环节出错?

    问题出在Java的默认信任库(truststore)中没有包含ynslyszx.com的证书链中的某个或多个中间证书。虽然myssl.com验证了证书是有效的,但它并不涉及Java运行时的信任库配置。Java运行时(如JDK)使用一个内置的或可配置的信任库来验证SSL/TLS连接的证书链。如果证书链中的某个中间证书不在信任库中,Java将无法构建完整的证书路径,从而导致PKIX path building failed错误。

  2. 服务器中尝试用myssl.com修复过证书,也是请求不通。

    修复证书可能只解决了服务器端的证书问题,但客户端(在这个例子中是Java环境)仍然需要能够验证服务器证书的完整性和有效性。如果Java的信任库中没有必要的中间证书,即使服务器证书是新的和有效的,客户端也会因为无法验证证书链而拒绝连接。

  3. 目前解决办法是使okhttp3忽略全部证书验证,但是这样不太合适,请问是否有其他解决方案?

    是的,忽略证书验证(例如,通过自定义TrustManager来接受所有证书)虽然可以解决问题,但会极大地降低安全性,因为它使你的应用程序容易受到中间人攻击(MITM)。更安全的解决方案包括:

    • 更新Java信任库:如果你控制Java运行环境,可以尝试将缺失的中间证书添加到Java的默认信任库中。这通常涉及下载中间证书,然后使用keytool工具将其导入到cacerts文件中。
    • 使用自定义TrustManager:如果你不想修改全局信任库,可以只在你的应用程序中使用一个自定义的TrustManager,该TrustManager仅信任特定的证书或证书链。这比完全忽略证书验证更安全,但你需要确保只信任可靠的证书。
    • 与服务器管理员合作:联系ynslyszx.com的服务器管理员,要求他们提供完整的证书链,并确保所有必要的中间证书都正确配置在服务器上。这样,客户端(包括Java环境)就能更容易地验证服务器证书。
    • 使用系统属性或JVM参数:在某些情况下,你可以通过系统属性或JVM参数来指定一个不同的信任库文件,该文件包含了你需要的所有证书。

    推荐的做法是尽可能更新和配置信任库,以包含所有必要的证书,从而保持应用程序的安全性。

 类似资料:
  • null openssl pkcs12-export-in cert1.pem-inkey privkey1.pem-out cert_and_key.p12-name certificate-cafile fullchain1.pem-caname root keytool-importKeystore-destStorePAS5W0RD123-destKeypass Pas5w0rd123-d

  • 问题内容: 这段代码 给我这个错误 我对SSL几乎一无所知,但我曾尝试下载该站点的证书并使用该选项指向该文件,但是它没有用。我想念什么吗? 问题答案: 正如评论中已经指出的那样:从SSLLabs报告中可以看出,该网站的SSL实施不正确。该报告中有关您的问题的主要部分是: 该服务器的证书链不完整。等级上限为B。 这意味着服务器没有发送验证证书所需的完整证书链。这意味着您需要在验证时自行添加丢失的证书

  • null 有人能帮帮我吗?谢谢。 代码 斯塔克特莱斯

  • 问题内容: 一般来说,我从GoDaddy获得了3个文件: 主证书文件 服务器私钥 捆绑文件 通过以下方式在Go服务器中配置了所有这些文件: 网络服务器运行正常,当前发布在。 我使用验证了我的SSL ,它的响应是 您可以转到此链接查看所有详细结果。 我想念什么? 问题答案: 在该线程之后,并从doc中开始: 如果证书是由证书颁发机构签名的,则certFile应该是服务器证书,任何中间件和CA证书的串

  • 问题内容: 我正在尝试固定服务器的自签名证书。我的OkHttpClient使用两个参数,第一个是ssl Socket Factory: 其次是证书固定器: 注意:如果我不添加certificatePinner,则一切正常。问题是执行请求时,将调用CertificatePinner.check(): 显然,如果我确实设置了一个(非空的)certificatePinner,则该方法不会在那里停止,而是

  • > 。 有些帖子说x509是用来生成自签名证书的。 但使用时出错: 请告诉我哪条路是正确的。如果是正确的,如何解决错误?非常感激!

  • 问题内容: 我遇到客户端https请求的问题。 片段可以如下所示: 我得到的是错误:证书链中的自签名证书。 使用邮递员时,我可以导入客户端证书和密钥,并且可以毫无问题地使用它。有没有可用的解决方案?我还希望对邮递员如何处理证书和工作方式有所了解。 问题答案: 根据您的问题,我想您正在使用SSL通讯的自签名证书进行开发。 如果是这种情况,请在您正在运行节点的任何地方或直接使用 这指示节点允许不信任的