我正在尝试使用 OpenLiberty 中配置的特定于主机的出站 SSL 配置来建立与远程系统的 https 连接(在本例中为 Apple Pay,但我认为不相关)。
我知道密钥库、密码和协议是正确的,因为当我完全以编程方式执行此操作时,如https://stackoverflow.com/a/63080443/796761所示,连接和请求完全正常工作。
但是,当我删除所有密钥库/SSL 设置并尝试退回到我在
server.xml
中配置的内容时,我得到的错误与我根本没有设置 SSL 时得到的错误相同。 (在本例中是 java.io.IOException: HTTP/1.1 header parser received no bytes
。)
相关
server.xml
元素:
<featureManager>
<feature>webProfile-8.0</feature> <!-- adds ssl-1.0 -->
...
</featureManager>
...
<keyStore id="applePayKeyStore" location="c:/keys/MerchID.AZMVDNOW.p12" password="redacted"/>
<ssl id="applePaySSL" keyStoreRef="applePayKeyStore" clientAuthentication="true" sslProtocol="TLSv1.2">
<outboundConnection host="apple-pay-gateway-cert.apple.com"/>
</ssl>
Java代码:
HttpRequest request = HttpRequest.newBuilder().uri(validationEndpoint)
.header("Content-Type", "application/json")
.POST(BodyPublishers.ofString(jsonRequest))
.build();
HttpClient client = HttpClient.newBuilder().build();
return client.send(request, BodyHandlers.ofString()).body();
其中
validationEndpoint
设置为 https://apple-pay-gateway-cert.apple.com/paymentservices/paymentSession
同样,如果我将上面的
client
替换为以下内容,请求就会成功:
char[] passwordChars = keystorePassword.toCharArray();
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream("/keys/MerchID.AZMVDNOW.p12"), passwordChars);
KeyManagerFactory keyMgrFactory = KeyManagerFactory.getInstance("SunX509");
keyMgrFactory.init(keyStore, passwordChars);
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(keyMgrFactory.getKeyManagers(), null, null);
SSLParameters sslParam = new SSLParameters();
sslParam.setNeedClientAuth(true);
HttpClient client = HttpClient.newBuilder()
.sslContext(sslContext)
.sslParameters(sslParam).build();
OpenLiberty 24.0.0.6,JDK 17
那么,问题是如何让 Liberty 在与指定服务器建立 https 连接时使用这个特定的密钥库?
到目前为止,我还没有找到使用已配置的 SSL 配置自动与 Liberty 建立此类连接的示例,所以我希望我只是缺少一些简单的粘合剂。
javax.net.debug=ssl
没有告诉我任何有用的信息:
[err] javax.net.ssl|DEBUG|69|HttpClient-1-Worker-0|2024-07-12 20:30:31.041 UTC|SSLCipher.java:1870|KeyLimit read side: algorithm = AES/GCM/NOPADDING:KEYUPDATE
countdown value = 137438953472
[err] javax.net.ssl|DEBUG|69|HttpClient-1-Worker-0|2024-07-12 20:30:31.041 UTC|SSLCipher.java:2024|KeyLimit write side: algorithm = AES/GCM/NOPADDING:KEYUPDATE
countdown value = 137438953472
[err] javax.net.ssl|DEBUG|69|HttpClient-1-Worker-0|2024-07-12 20:30:31.051 UTC|SSLCipher.java:1870|KeyLimit read side: algorithm = AES/GCM/NOPADDING:KEYUPDATE
countdown value = 137438953472
[err] javax.net.ssl|ALL|69|HttpClient-1-Worker-0|2024-07-12 20:30:31.053 UTC|X509Authentication.java:223|No X.509 cert selected for [RSA, EC]
[err] javax.net.ssl|DEBUG|69|HttpClient-1-Worker-0|2024-07-12 20:30:31.053 UTC|SSLCipher.java:2024|KeyLimit write side: algorithm = AES/GCM/NOPADDING:KEYUPDATE
countdown value = 137438953472
[err] javax.net.ssl|DEBUG|91|Finalizer thread|2024-07-12 20:30:31.127 UTC|SSLSocketImpl.java:577|duplex close of SSLSocket
[err] javax.net.ssl|DEBUG|91|Finalizer thread|2024-07-12 20:30:31.129 UTC|SSLSocketImpl.java:1785|close the SSL connection (passive)
使用 Liberty SSL 跟踪,看起来相关对象已成功加载,包括显示 Liberty 能够在存储中查看证书的条目:
[7/12/24, 20:49:04:920 UTC] 00000031 id=00000000 com.ibm.ws.ssl.config.WSKeyStore 3 别名:apple pay 商家身份证书
并将主机名映射到配置:
[7/12/24, 20:49:05:241 世界标准时间] 00000031 id=00000000 com.ibm.ws.channel.ssl.internal.SSLChannelProvider 3 设置SSL配置 id=applePaySSL {com.ibm.ws.ssl.internal.RepertoireConfigService, com.ibm.wsspi.ssl.SSLConfiguration}={verifyHostname=false, 服务范围=捆绑, component.name=com.ibm.ws.ssl.internal.RepertoireConfigService, TrustStore.target=(service.pid=com.ibm.ws.ssl.keystore_0), trustDefaultCerts = false, KeyStore.target=(service.pid=com.ibm.ws.ssl.keystore_0), sslProtocol=TLSv1.2,config.source=文件, outboundConnection.0.host=apple-pay-gateway-cert.apple.com, id=applePaySSL, service.pid=com.ibm.ws.ssl.repertoire_0, clientAuthenticationSupported=false,service.id=621, keyStoreRef=com.ibm.ws.ssl.keystore_0,enforceCipherOrder=false, 服务.bundleid=132, outboundConnection.0.config.referenceType=com.ibm.ws.ssl.repertoire.config.outboundConnection, osgi.ds.satisfying.condition.target=(osgi.condition.id=true), config.overrides=true,clientAuthentication=true,component.id=487, effectiveTrustStore=com.ibm.ws.ssl.keystore_0, config.id=com.ibm.ws.ssl.repertoire[applePaySSL],securityLevel=高, service.factoryPid=com.ibm.ws.ssl.repertoire,service.vendor=IBM, config.displayId=ssl[applePaySSL]}
但我认为出站连接使用的是
defaultSSLConfig
而不是applePaySSL
:
[7/12/24, 20:50:43:868 UTC] 00000046 id=00000000 com.ibm.ws.ssl.SSLPropertyUtils > LookupProperties alias=defaultSSLConfig 条目 [7/12/24, 20:50:43:868 UTC] 00000046 id=00000000 com.ibm.ws.ssl.SSLPropertyUtils > getProperties sslAliasName=defaultSSLConfig currentConnectionInfo={com.ibm.ssl.direction=出站}
我无法将整个巨大的跟踪粘贴到这里,但如果需要的话可以提供细节。
我最近遇到了类似的问题。
下面是 Liberty 代码中的示例跟踪片段。它显示了将出站连接请求中的主机名和端口与 server.xml 中配置的主机名和端口进行匹配的过程。
在我的例子中,跟踪表明请求带有主机名,而 server.xml 配置了主机的 IP 地址。我希望您找到一个类似的片段可以阐明您的问题
[06/06/24 11:41:38:461 EDT] 00000037 OutboundSSLSe 3 SSLConfig dynamic selection info: 192.168.252.10,123
[06/06/24 11:41:38:461 EDT] 00000037 OutboundSSLSe 3 This entry has 2 attributes.
[06/06/24 11:41:38:461 EDT] 00000037 OutboundSSLSe 3 Host: 192.168.252.10, Port: 123
[06/06/24 11:41:38:461 EDT] 00000037 OutboundSSLSe 3 Host does not match.