来自 OpenLiberty 与自定义密钥库的相互 TLS 连接

问题描述 投票:0回答:1

我正在尝试使用 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)

编辑2:

使用 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=出站}

我无法将整个巨大的跟踪粘贴到这里,但如果需要的话可以提供细节。

java ssl websphere-liberty open-liberty java-http-client
1个回答
0
投票

我最近遇到了类似的问题。

下面是 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.
© www.soinside.com 2019 - 2024. All rights reserved.