Web 服务客户端 - 带有密钥库
web-service client - with keystore
我需要创建一个带有密钥库的 Web 服务客户端。但这是错误:
sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target
我的代码:
private SSLSocketFactory getFactory() throws Exception {
File pKeyFile = new ClassPathResource("jks/dex-client-issuer-wss.jks").getFile();
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("PKIX");
KeyStore keyStore = KeyStore.getInstance("JKS");
InputStream keyInput = new FileInputStream(pKeyFile);
keyStore.load(keyInput, pass.toCharArray());
keyInput.close();
keyManagerFactory.init(keyStore, pass.toCharArray());
SSLContext context = SSLContext.getInstance("TLS");
context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());
return context.getSocketFactory();
}
这是 http 连接:
URL url = new URL("https://dexxis-demo1.gemalto.com/DEX/communication/issuer-interface");
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setSSLSocketFactory(getFactory());
我只有一个与 soap 一起使用的 dex-client-issuer-wss.jks 文件 ui,如何创建与该证书文件的连接?
'unable to find valid certification path'(在 SSL/TLS 握手期间)与您的密钥库无关——这意味着 server 证书不会针对您的 truststore,因为您将 null 作为第二个参数传递给 context.init
,所以它是 JRE 的默认值,它是 sysprop javax.net.ssl.trustStore
指定的文件,否则 JRE/lib/security/cacerts
](或 .../jssecacerts
如果存在)。
该服务器正在使用根证书 Gemalto Business Root Certificate Authority
下颁发的证书,该证书不包含在随 Oracle Java 包提供的 cacerts 中,或者我知道的任何其他已建立的信任库中,并且不知道通过 public 透明度日志(根据 https://crt.sh)。 SoapUI,大概是因为它被设计为开发、测试和调试工具,忽略无效或可疑的证书,但浏览器或 curl
或 wget
上的 URL 应该失败,除非信任库( s) 在您的系统上已被修改或不正常。
OTOH openssl s_client
主要也是一个调试工具 报告 一个错误,但无论如何都会建立连接。
如果您确实想要信任该 CA,或其(两个)中间人之一,或者该站点,则您需要在您的信任库中拥有适当的证书。 通常 做法是信任根 CA 证书,但 Java 支持使用链中的任何证书,包括 EE 证书,作为锚点。由于您已经在创建自己的上下文和密钥管理器,因此您不妨创建自己的信任管理器,而不是修改 JRE 默认值,后者(通常)依赖于 platform/environment,有时也很棘手。您可以获取所需的证书并将其放入单独的密钥库文件中(见下文),加载该文件并使用它来创建信任管理器。或者,由于您已经拥有自己的密钥+证书的密钥库文件,Java 支持拥有一个或多个 privateKey 条目 和 一个或多个 trustedCert 条目或其他 party/parties 在同一个文件中,因此您可以将他们的证书添加到现有的 JKS 中,并在 TrustManagerFactory
中使用相同的 KeyStore
对象,就像 KeyManagerFactory
创建您的上下文的 trustmanager 数组。
获得证书的简单方法是:
openssl s_client -showcerts -connect host:port </dev/null
(在 Windows <NUL:
上)——使用端口 443;现在许多服务器需要服务器名称指示扩展(又名 SNI),对于低于 1.1.1 的 OpenSSL,您必须添加 -servername host
来提供它,但该服务器不需要。这会为来自服务器的每个证书输出一个 PEM 块,每个证书之前的标签显示 s: (subjectname)
和 i: (issuername)
。请注意,在第一个证书(EE 证书需要)之后,此服务器以自上而下的顺序而不是自下而上的顺序发送 CA 证书。这在技术上违反了 RFC 5246(或更早的 4346 或 2246); TLS1.3 的 RFC 8446 允许它,因为它已经是一个通用扩展,Java JSSE 特别支持它。
keytool -printcert -rfc -sslserver host
-- 也支持 host:port
但默认为 443,这对您来说没问题。这仅输出 PEM 块,因此如果您还不知道我之前的项目中关于顺序的信息,您将不得不解码每个块以找出哪个是哪个,或者只是试验直到找到正确的块。
在任何一种情况下,获取所需的 PEM 块并将其放入文件中,然后执行
keytool -importcert -keystore jksfile -alias somealias -file thecertfile
somealias
仅 要求 在文件中是唯一的(如果将它放在自己的文件中,这是微不足道的)并且不区分大小写(通常是小写) , 但应该是描述性的或助记性的,并且尽可能只使用字母数字。然后使用上面生成的文件。
我需要创建一个带有密钥库的 Web 服务客户端。但这是错误:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
我的代码:
private SSLSocketFactory getFactory() throws Exception {
File pKeyFile = new ClassPathResource("jks/dex-client-issuer-wss.jks").getFile();
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("PKIX");
KeyStore keyStore = KeyStore.getInstance("JKS");
InputStream keyInput = new FileInputStream(pKeyFile);
keyStore.load(keyInput, pass.toCharArray());
keyInput.close();
keyManagerFactory.init(keyStore, pass.toCharArray());
SSLContext context = SSLContext.getInstance("TLS");
context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());
return context.getSocketFactory();
}
这是 http 连接:
URL url = new URL("https://dexxis-demo1.gemalto.com/DEX/communication/issuer-interface");
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setSSLSocketFactory(getFactory());
我只有一个与 soap 一起使用的 dex-client-issuer-wss.jks 文件 ui,如何创建与该证书文件的连接?
'unable to find valid certification path'(在 SSL/TLS 握手期间)与您的密钥库无关——这意味着 server 证书不会针对您的 truststore,因为您将 null 作为第二个参数传递给 context.init
,所以它是 JRE 的默认值,它是 sysprop javax.net.ssl.trustStore
指定的文件,否则 JRE/lib/security/cacerts
](或 .../jssecacerts
如果存在)。
该服务器正在使用根证书 Gemalto Business Root Certificate Authority
下颁发的证书,该证书不包含在随 Oracle Java 包提供的 cacerts 中,或者我知道的任何其他已建立的信任库中,并且不知道通过 public 透明度日志(根据 https://crt.sh)。 SoapUI,大概是因为它被设计为开发、测试和调试工具,忽略无效或可疑的证书,但浏览器或 curl
或 wget
上的 URL 应该失败,除非信任库( s) 在您的系统上已被修改或不正常。
OTOH openssl s_client
主要也是一个调试工具 报告 一个错误,但无论如何都会建立连接。
如果您确实想要信任该 CA,或其(两个)中间人之一,或者该站点,则您需要在您的信任库中拥有适当的证书。 通常 做法是信任根 CA 证书,但 Java 支持使用链中的任何证书,包括 EE 证书,作为锚点。由于您已经在创建自己的上下文和密钥管理器,因此您不妨创建自己的信任管理器,而不是修改 JRE 默认值,后者(通常)依赖于 platform/environment,有时也很棘手。您可以获取所需的证书并将其放入单独的密钥库文件中(见下文),加载该文件并使用它来创建信任管理器。或者,由于您已经拥有自己的密钥+证书的密钥库文件,Java 支持拥有一个或多个 privateKey 条目 和 一个或多个 trustedCert 条目或其他 party/parties 在同一个文件中,因此您可以将他们的证书添加到现有的 JKS 中,并在 TrustManagerFactory
中使用相同的 KeyStore
对象,就像 KeyManagerFactory
创建您的上下文的 trustmanager 数组。
获得证书的简单方法是:
openssl s_client -showcerts -connect host:port </dev/null
(在 Windows<NUL:
上)——使用端口 443;现在许多服务器需要服务器名称指示扩展(又名 SNI),对于低于 1.1.1 的 OpenSSL,您必须添加-servername host
来提供它,但该服务器不需要。这会为来自服务器的每个证书输出一个 PEM 块,每个证书之前的标签显示s: (subjectname)
和i: (issuername)
。请注意,在第一个证书(EE 证书需要)之后,此服务器以自上而下的顺序而不是自下而上的顺序发送 CA 证书。这在技术上违反了 RFC 5246(或更早的 4346 或 2246); TLS1.3 的 RFC 8446 允许它,因为它已经是一个通用扩展,Java JSSE 特别支持它。keytool -printcert -rfc -sslserver host
-- 也支持host:port
但默认为 443,这对您来说没问题。这仅输出 PEM 块,因此如果您还不知道我之前的项目中关于顺序的信息,您将不得不解码每个块以找出哪个是哪个,或者只是试验直到找到正确的块。
在任何一种情况下,获取所需的 PEM 块并将其放入文件中,然后执行
keytool -importcert -keystore jksfile -alias somealias -file thecertfile
somealias
仅 要求 在文件中是唯一的(如果将它放在自己的文件中,这是微不足道的)并且不区分大小写(通常是小写) , 但应该是描述性的或助记性的,并且尽可能只使用字母数字。然后使用上面生成的文件。