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 到您的应用程序支持的最新版本。
我有自己的客户私钥和证书,我已经将它们放在密钥库中,服务器 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 到您的应用程序支持的最新版本。