java - 有没有一种方法可以在不直接访问 Java 中的 Websphere keystore 的情况下执行相互 SSL?

标签 java ssl websphere keystore mutual-authentication

我正在尝试在 2 个 Websphere 8.5.5 服务器之间建立相互 SSL。我将它们称为 ServerA 和 ServerB。

ServerA:客户端,将ServerB的SSL证书添加到DefaultTrustKeyStore。

ServerB:服务器端,将ServerA的SSL证书添加到DefaultTrustKeyStore中。我还安装了一个 WAR,它提供了一个可以接收 HTTP POST 消息、记录它并向客户端响应“OK”的 servlet。客户端身份验证模式设置为“必需”。

现在我遇到了一个问题:Mutual SSL 客户端的传统方式必须直接读取 keystore 以检索私钥,因此我们可以使用它来设置我们的 SSLContext 来进行客户端身份验证。但它可能存在直接访问 keystore 的安全漏洞。所以我需要找到一种方法,如果我能让我的 ServerA 的 websphere 为我做这件事(或者可以命令 Websphere 做这件事的 Java 代码)。

谁能教我如何在不直接访问 keystore 的情况下执行此操作,好吗?


更新:

你好 dbreaux。

我试过你的方式做一个环回连接,但它似乎不起作用。

这是最后一部分的 SSL 调试日志:

[2017/9/3   21:06:25:284 CST] 00000099 SystemOut     O JsseJCE:  Using KeyGenerator IbmTlsPrf from provider TBD via init 
[2017/9/3   21:06:25:284 CST] 00000099 SystemOut     O HandshakeMessage:  TLS Keygenerator IbmTlsPrf  from provider from init IBMJCE version 1.8
[2017/9/3   21:06:25:284 CST] 00000099 SystemOut     O WebContainer : 3, WRITE: TLSv1 Change Cipher Spec, length = 1
[2017/9/3   21:06:25:285 CST] 00000099 SystemOut     O JsseJCE:  Using cipher AES/CBC/NoPadding from provider TBD via init 
[2017/9/3   21:06:25:285 CST] 00000099 SystemOut     O CipherBox:  Using cipher AES/CBC/NoPadding from provider from init IBMJCE version 1.8
[2017/9/3   21:06:25:285 CST] 00000099 SystemOut     O JsseJCE:  Using MAC HmacSHA1 from provider TBD via init 
[2017/9/3   21:06:25:285 CST] 00000099 SystemOut     O MAC:  Using MessageDigest HmacSHA1 from provider IBMJCE version 1.8
[2017/9/3   21:06:25:285 CST] 00000099 SystemOut     O *** Finished
[2017/9/3   21:06:25:285 CST] 00000099 SystemOut     O verify_data:  { 226, 248, 159, 68, 107, 196, 76, 219, 134, 227, 129, 58 }
[2017/9/3   21:06:25:285 CST] 00000099 SystemOut     O ***
[2017/9/3   21:06:25:285 CST] 00000099 SystemOut     O WebContainer : 3, WRITE: TLSv1 Handshake, length = 48
[2017/9/3   21:06:25:285 CST] 00000099 SystemOut     O WebContainer : 3, waiting for close_notify or alert: state 1
[2017/9/3   21:06:25:285 CST] 00000099 SystemOut     O WebContainer : 3, Exception while waiting for close java.net.SocketException: Software caused connection abort: recv failed
[2017/9/3   21:06:25:285 CST] 00000099 SystemOut     O %% Invalidated:  [Session-27, SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA]
[2017/9/3   21:06:25:285 CST] 00000099 SystemOut     O WebContainer : 3, SEND TLSv1 ALERT:  fatal, description = handshake_failure
[2017/9/3   21:06:25:285 CST] 00000099 SystemOut     O WebContainer : 3, WRITE: TLSv1 Alert, length = 32
[2017/9/3   21:06:25:285 CST] 00000099 SystemOut     O WebContainer : 3, Exception sending alert: java.net.SocketException: Software caused connection abort: socket write error
[2017/9/3   21:06:25:285 CST] 00000099 SystemOut     O WebContainer : 3, called closeSocket()
[2017/9/3   21:06:25:285 CST] 00000099 SystemOut     O WebContainer : 3, handling exception: javax.net.ssl.SSLHandshakeException: java.net.SocketException: Software caused connection abort: recv failed

我正在使用 WAS 生成的 DefaultKeyStores。由于动态出站端点页面一直给我 CWPKI0681E 错误,所以我采用了您的第一种方式。

这对你有效吗?还是因为我使用的是 WAS 生成的默认 CA?


11/06 更新:

我发现一些线索可能有助于解决这个问题。我尝试使用 OpenSSL 建立到服务器的客户端连接,并且有一些有趣的东西。

首先,我使用我的客户端 WAS 连接到服务器端 WAS,我最终遇到了这个异常,服务器刚刚断开了我的连接。这是服务器端日志:

[2017/11/3   18:07:19:349 CST] 00000070 SystemOut     O WebContainer : 0, WRITE: TLSv1 Handshake, length = 2765
[2017/11/3   18:07:19:355 CST] 00000070 SystemOut     O WebContainer : 0, READ: TLSv1 Handshake, length = 77
[2017/11/3   18:07:19:355 CST] 00000070 SystemOut     O *** Certificate chain
[2017/11/3   18:07:19:355 CST] 00000070 SystemOut     O ***
[2017/11/3   18:07:19:357 CST] 00000070 SystemOut     O WebContainer : 0, fatal error: 40: null cert chain
javax.net.ssl.SSLHandshakeException: null cert chain
[2017/11/3   18:07:19:357 CST] 00000070 SystemOut     O %% Invalidated:      [Session-1, SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA]
[2017/11/3   18:07:19:357 CST] 00000070 SystemOut     O WebContainer : 0, SEND TLSv1 ALERT:  fatal, description = handshake_failure
[2017/11/3   18:07:19:358 CST] 00000070 SystemOut     O WebContainer : 0, WRITE: TLSv1 Alert, length = 2
[2017/11/3   18:07:19:358 CST] 00000070 SystemOut     O WebContainer : 0, fatal: engine already closed.  Rethrowing javax.net.ssl.SSLHandshakeException: null cert chain

现在我尝试使用以下命令将服务器与 OpenSSL 连接,ClientCA.key 是我的私钥:

openssl s_client -tls1 -connect 192.168.1.20:9443 -key ClientCA.key  -state

CONNECTED(00000168)
SSL_connect:before SSL initialization
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS read server hello
depth=1 C = US, O = IBM, OU = TestNode01, OU = TestNode01Cell, OU = Root    Certificate, CN = Test
verify error:num=19:self signed certificate in certificate chain
SSL_connect:SSLv3/TLS read server certificate
SSL_connect:SSLv3/TLS read server key exchange
SSL_connect:SSLv3/TLS read server certificate request
SSL_connect:SSLv3/TLS read server done
SSL_connect:SSLv3/TLS write client certificate
SSL_connect:SSLv3/TLS write client key exchange
SSL_connect:SSLv3/TLS write change cipher spec
SSL_connect:SSLv3/TLS write finished
SSL_connect:error in SSLv3/TLS write finished
write:errno=0
...

我掉线了,在日志末尾也看到了同样的异常。但是如果我用我的证书发出命令:

openssl s_client -tls1 -connect 192.168.1.20:9443 -cert ClientCA.crt -key ClientCA.pfx  -state

CONNECTED(00000150)
SSL_connect:before SSL initialization
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS read server hello
depth=1 C = US, O = IBM, OU = SAGE-AD2Node01, OU = SAGE-AD2Node01Cell, OU = Root Certificate, CN = SAGE-AD2
verify error:num=19:self signed certificate in certificate chain
SSL_connect:SSLv3/TLS read server certificate
SSL_connect:SSLv3/TLS read server key exchange
SSL_connect:SSLv3/TLS read server certificate request
SSL_connect:SSLv3/TLS read server done
SSL_connect:SSLv3/TLS write client certificate
SSL_connect:SSLv3/TLS write client key exchange
SSL_connect:SSLv3/TLS write certificate verify
SSL_connect:SSLv3/TLS write change cipher spec
SSL_connect:SSLv3/TLS write finished
SSL_connect:SSLv3/TLS write finished
SSL_connect:SSLv3/TLS read change cipher spec
SSL_connect:SSLv3/TLS read finished
...

我已连接到服务器!和服务器日志看起来也不一样:

[2017/11/6   16:19:55:246 CST] 00000073 SystemOut     O WebContainer : 0, WRITE: TLSv1 Handshake, length = 2765
[2017/11/6   16:19:55:309 CST] 00000073 SystemOut     O WebContainer : 0, READ: TLSv1 Handshake, length = 853
[2017/11/6   16:19:55:309 CST] 00000073 SystemOut     O *** Certificate chain
[2017/11/6   16:19:55:309 CST] 00000073 SystemOut     O chain [0] = [
[
  Version: V1
  ...

所以我怀疑我一定是在我的客户端 WAS 上遗漏了一些设置,所以它没有将我的证书发送到我的 P12 文件中的服务器。你能描述更多关于你如何实现它的细节吗? @Alaine @dbreaux

最佳答案

在 WebSphere 配置中,您似乎需要指定 keystore 中的客户端证书,以便在建立出站连接时出示。 (老实说,我不知道您是否可以编辑 Keystore 以设置其默认值。我看不到从管理控制台执行此操作的方法,但您可以从外部执行此操作。或者它已经设置好了,但是这还不够。)

但是您可以在 SSL 配置中明确设置它。我相信所有这些级别都应该有效,但承认我没有亲自尝试过。

您可以在 Cell/Node Default SSL Settings 中进行设置:

CellDefaultSSLSettings

或者对于范围,如 Cell、Node 或 Server:

Endpoint security configurations

Endpoint SSL configuration

或者您可以根据要连接的目的地进行设置:

Dynamic Outbound SSL Configuration

关于java - 有没有一种方法可以在不直接访问 Java 中的 Websphere keystore 的情况下执行相互 SSL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45758193/

相关文章:

java - Java 中关闭数据库连接

java - 构造 BufferedReader,以 BufferedReader 作为读取器

java - 仍然缺少 jenkins bitbucket 分支源插件的自签名证书

Java信任库

ios - TiWebView : Submitting data to a self signed https URL from a local html file on iOS cause error

java - corbaloc : URLs load balanced? 怎么样

java - 用于 WebSphere Portal 开发的轻量级门户服务器?

java - 哪个内存用于从 java 运行的外部进程 - java 堆空间或操作系统内存?

Java HashMap 检测冲突

jsf - 部署到 WebSphere Liberty 8.5.5.6 时解析 OmniFaces 2.1 Taglib 时出错