Web 服务客户端 - 使用密钥库



我需要创建一个带有密钥库的 Web 服务客户端。但这是错误:

sun.security.provider.certpath.sunCertPathBuilderException: 无法 查找所请求目标的有效证书路径

我的代码:

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 ui 的 dex-client-issuer-wss.jks 文件,如何与此证书文件建立连接?

">

找不到有效的证书路径"(在SSL/TLS握手期间(与您的密钥库无关 - 这意味着服务器证书不会针对您的信任库进行验证,因为您将null作为第二个参数传递给context.init是JRE的默认值,这是sysprop指定的文件javax.net.ssl.trustStore如果以其他方式设置JRE/lib/security/cacerts(如果存在,则.../jssecacerts(。

该服务器正在使用根证书Gemalto Business Root Certificate Authority下颁发的证书,该证书未包含在 Oracle Java 软件包或我知道的任何其他已建立的信任库中,并且公共透明度日志(根据 https://crt.sh(不知道。SoapUI,大概是因为它被设计为开发、测试和调试工具,忽略无效或可疑的证书,但该 URL 上的浏览器或curlwget应该会失败,除非系统上的信任库已被修改或异常。 OTOHopenssl s_client也主要是一个调试工具,它会报告错误,但无论如何都会建立连接。

如果您确实想要信任该 CA、其(两个(中间体之一或站点,则需要在信任库中具有相应的证书。通常的做法是信任根 CA 证书,但 Java 支持使用链中的任何证书(包括 EE 证书(作为锚点。由于您已经在创建自己的上下文和密钥管理器,因此您不妨创建自己的信任管理器,而不是修改 JRE 默认值,这(通常(依赖于平台/环境,有时很棘手。您可以获取所需的证书并将其放在单独的密钥库文件中(见下文(,加载该文件并使用它来创建信任管理器。或者,由于您已经拥有自己的密钥+证书的密钥库文件,Java 支持在同一文件中同时包含一个或多个私钥条目和其他方的 trustedCert 条目,因此您只需将其证书添加到现有 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(;RFC 8446 for TLS1.3 允许它,因为它已经是一个通用扩展,Java JSSE 特别支持它。

  • keytool -printcert -rfc -sslserver host-- 也支持host:port但默认值为 443,这对您来说没问题。这仅输出 PEM 块,因此,如果您还没有从我之前的项目中了解订单,则必须解码每个模块以找出哪个是哪个,或者只是进行实验,直到找到正确的一个。

在任何一种情况下,获取所需的 PEM 块并将其放入文件中,然后执行

keytool -importcert -keystore jksfile -alias somealias -file thecertfile

somealias只需要在文件中是唯一的(如果您将其放在自己的文件中,则微不足道(和不区分大小写(通常为小写(,但应该是描述性的或助记符,并且仅在可能的情况下是字母数字。然后使用上述结果文件。

相关内容

  • 没有找到相关文章

最新更新