Google 云功能 - 尝试 2 种方式的 ssl 握手但出现错误无法找到请求目标的有效证书路径

Google cloud function - trying 2 way ssl handshake but getting error unable to find valid certification path to requested target

我有自己的客户私钥和证书,我已经将它们放在密钥库中,服务器 public 证书根和中间我已经创建了信任库并将它们放入其中。我正在尝试 ssl 握手但无法这样做。我有以下代码片段,不确定哪里出了问题

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
                KeyStore keystore = KeyStore.getInstance("JKS");
                keystore.load(keystoreStream, "mypass".toCharArray());
                kmf.init(keystore, "mypass".toCharArray());
                KeyManager[] keyManagers = kmf.getKeyManagers();
                keystoreStream.close();
                keystoreStream = null;
                
                
                TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                KeyStore truststore = KeyStore.getInstance("JKS");
                truststore.load(truststoreStream, "mypass".toCharArray());
                tmf.init(truststore);
                TrustManager[] trustManagers = tmf.getTrustManagers();
                truststoreStream.close();
                truststoreStream = null;
                
                SSLContext sslContext = SSLContext.getInstance("SSL");
                sslContext.init(keyManagers, trustManagers, null);
                
                if (urlConnection instanceof HttpsURLConnection) {
                    HttpsURLConnection httpURLConnection = (HttpsURLConnection) urlConnection;
                    httpURLConnection.setRequestMethod("POST");
                    httpURLConnection.setSSLSocketFactory(sslContext.getSocketFactory());
                    //error on below line                   
                    httpURLConnection.connect();

                    OutputStreamWriter wr = new OutputStreamWriter(urlConnection.getOutputStream());
                    wr.write(requestData.toString());
                    wr.flush();

                    responseCode = httpURLConnection.getResponseCode();
                }
            }

错误-

javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

问题是由 self-signed 证书(证书颁发机构未对其签名)或 Java 信任库中不存在的证书链引起的。

作为解决方法,您可以将此证书添加到 JVM 的受信任证书列表中。

  • 首先您可以检查您的证书是否已经在信任库中 通过 运行 以下命令:keytool -list -keystore "$JAVA_HOME/jre/lib/security/cacerts" (您不需要提供 密码)。

    如果您的证书丢失,您可以通过使用 您的浏览器并使用以下命令将其添加到信任库:

    keytool -import -noprompt -trustcacerts -alias <AliasName> -file <certificate> -keystore <KeystoreFile> -storepass <Password>

    或者你可以参考这个thread

  • 重要的是您看到正在使用正确的信任库。 如果配置了-Djavax.net.ssl.trustStore,会覆盖 默认信任库的位置,需要 已检查。

  • 此外,您可能有多个 JRE/JDKs,有时可能是一个 混乱的来源。因此,请确保证书已 导入到正确的信任库中。

  • 检查您的防病毒工具是否阻止了“SSL 扫描”SSL/TLS。如果 确实如此,禁用此功能或为目标设置例外 地址。

  • 验证目标服务器是否配置为正确提供 SSL。 这可以通过 SSL Server Test tool.

    来完成
  • 如果上述操作失败,您的信任库可能已过时。升级 Java 到您的应用程序支持的最新版本。