我有一个cert文件,该文件在一个Open Liberty实例(jdk-11.0.5 + 10-openj9下的20.0.0.2版)下可以正常工作,可以使用标准HttpsURLConnection向使用cert-auth的特定端点进行出站调用。在具有相同版本/ JDK的单独服务器上,我正在使用MicroProfile REST客户端API(如果需要的话,使用@Asynchronous)创建一个新应用,但是调用失败,握手失败。我正在使用相同的证书和相同的密钥库配置(并且在两个服务器上都启用了“ ssl-1.0”功能)...

<keyStore id="defaultKeyStore" location="key.jks" password="changeit" type="jks"/>


我尝试在两台服务器下都使用“ -Djavax.net.debug = all”进行调试,发现在服务器启动时都找到了具有我的目标别名的证书并将其添加为受信任证书。

SunX509KeyManagerImpl.java:164|found key for : my-alias (...)
X509TrustManagerImpl.java:79|adding as trusted certificates (...)
SSLContextImpl.java:115|trigger seeding of SecureRandom
SSLContextImpl.java:119|done seeding of SecureRandom


但是,对于mpRestClient应用程序,当我调用有问题的端点时,它似乎会自发地将信任库切换到默认的JDK cacerts信任库...

TrustStoreManager.java:112|trustStore is: C:\Program Files\AdoptOpenJDK\jdk-11.0.5+10-openj9\lib\security\cacerts
....
TrustStoreManager.java:311|Reload the trust store
TrustStoreManager.java:318|Reload trust certs
TrustStoreManager.java:323|Reloaded 88 trust certs
X509TrustManagerImpl.java:79|adding as trusted certificates (...)
SSLContextImpl.java:115|trigger seeding of SecureRandom
SSLContextImpl.java:119|done seeding of SecureRandom


经过一堆谈判之后,它最终变成了……

CertificateMessage.java:290|No X.509 certificate for client authentication, use empty Certificate message instead
CertificateMessage.java:321|Produced client Certificate handshake message (
  "Certificates": <empty list>
)
....
TransportContext.java:312|Fatal (HANDSHAKE_FAILURE): Couldn't kickstart handshaking (
  "throwable" : {
    javax.net.ssl.SSLException: readHandshakeRecord
    ....
  }
)


当然,没有找到用于客户端身份验证的证书,因为重新加载了整个信任库,从而清除了最初加载的信任库。信任库的这种自发切换不会在其他服务器下发生。该服务器上相关的成功行为是...

SunX509KeyManagerImpl.java:401|matching alias: my-alias
ServerHelloDone.java:151|Consuming ServerHelloDone handshake message (
  <empty>
)
CertificateMessage.java:321|Produced client Certificate handshake message (...)
SSLSocketOutputRecord.java:241|WRITE: TLS12 handshake, length = 3769
SSLSocketOutputRecord.java:255|Raw write (...)
RSAClientKeyExchange.java:193|Produced RSA ClientKeyExchange handshake message (...)
SSLSocketOutputRecord.java:241|WRITE: TLS12 handshake, length = 262
SSLSocketOutputRecord.java:255|Raw write (...)
CertificateVerify.java:743|Produced CertificateVerify handshake message (...)
SSLSocketOutputRecord.java:241|WRITE: TLS12 handshake, length = 264
SSLSocketOutputRecord.java:255|Raw write (...)
ChangeCipherSpec.java:115|Produced ChangeCipherSpec message
SSLSocketOutputRecord.java:225|Raw write (...)
Finished.java:398|Produced client Finished handshake message (...)
....
ChangeCipherSpec.java:149|Consuming ChangeCipherSpec message
....
SSLSocketInputRecord.java:249|READ: TLSv1.2 handshake, length = 64
SSLCipher.java:1329|Padded plaintext after DECRYPTION (...)
Finished.java:535|Consuming server Finished handshake message (...)
SSLSocketOutputRecord.java:309|WRITE: TLS12 application_data, length = 339
SSLCipher.java:1483|Padded plaintext before ENCRYPTION (...)
SSLSocketOutputRecord.java:323|Raw write (...)
...
SSLSocketInputRecord.java:249|READ: TLSv1.2 application_data, length = 544
SSLCipher.java:1329|Padded plaintext after DECRYPTION (...)
[...and then I get my decrypted response...]


两种服务器设置之间的另一个区别是,成功的设置是独立下载Open Liberty的javaee8版本,而失败的则是通过Maven执行的。

mvn liberty:dev -Ddebug=false -DskipTests=true


我不知道为什么那应该有什么不同,但显然是。配置几乎完全相同。我一直在寻找并尝试所有可能想到的东西,以进行修补,但是现在我对所产生的变化感到茫然。希望有人注意到。关键是使服务器运行mpRestClient应用,以停止自发将信任存储切换为JDK cacerts默认值。但是到目前为止,我尝试过的任何方法都不能阻止它。

最佳答案

最终,我认为这是一个错误,因此建议您在https://github.com/OpenLiberty/open-liberty/issues处打开一个问题(请务必参考此页面)。我认为您可以通过添加appSecurity-2.0功能来解决此问题。似乎JAX-RS需要SSL和AppSecurity功能,才能使用其他密钥存储。这就解释了ClassNotFoundException-如果安装了appSecurity-2.0(或3.0)功能,则JaxRsSSLManager类仅添加到框架的类路径中。

使用AppSecurity功能应该可以解决此问题,但是我认为这是一种解决方法。如果您打开OpenLiberty的问题,我们可以尝试在没有AppSecurity功能的情况下使其正常工作。

希望这会有所帮助,安迪

10-07 15:56
查看更多