Is there a way that I can do Mutual SSL without direct acces to the Websphere keystore in Java?

流过昼夜 提交于 2019-12-11 09:05:43

问题


I'm trying to establish Mutual SSL between 2 Websphere 8.5.5 servers. I'll just call them ServerA and ServerB.

ServerA: Client side, added ServerB's SSL certificate into DefaultTrustKeyStore.

ServerB: Server side, added ServerA's SSL certificate into DefaultTrustKeyStore. I also installed a WAR which provide a servlet that could receive HTTP POST message, log it, and response "OK" to client. Client Auth mode set to "Required".

Now I got a problem: traditional way of Mutual SSL client side MUST read the keystore directly to retrieve private key, so we can use it to set our SSLContext to do client authentication. But it might have security flaw for accessing keystore directly. So I need to find a way if I can let my ServerA's websphere to do this for me(or Java code that could command Websphere to do this).

Can anyone teach me how to do this without accessing keystore directly, please?


UPDATE:

Hi dbreaux.

I tried your way to do a loop-back connection, but it seem like not working.

Here's the SSL debug log last section:

[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

I'm using the DefaultKeyStores that WAS generated. Since the Dynamic Outbound Endpoint page keep giving me CWPKI0681E error, so I applied your first way.

Does this work on yours? or it's because I'm using the default CA that WAS generated?


11/06 UPDATE:

I found some clues might help to solve this. I tried to uses OpenSSL to establish client side connection to server, and there are some interesting stuff.

First, I use my client-side WAS to connect to the Server-side WAS, I end up with this exception and Server just dropped my connection. Here's server side log:

[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

Now I try to connect Server with OpenSSL with following command, ClientCA.key is my private 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
...

I got dropped and see same exception at the end of log too. But if I give command with my certificate:

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
...

I connected to Server! and server log look different too:

[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
  ...

So I suspect I must missed some setup on my Client-Side WAS, so it didn't send my certificate to Server which is inside of my P12 file. Can you describe more details about how you achieved it? @Alaine @dbreaux


回答1:


In the WebSphere configuration, it appears you need to specify a client certificate from the Keystore to present when making the outbound connection. (I honestly don't know if you can edit the Keystore to set its default. I don't see a way to do that from the admin console, but you might be able to from outside that. Or maybe it's already set, but this isn't sufficient.)

But a way you can set this explicitly is in the SSL Configurations. I believe all of these levels should work, but confess I haven't tried them personally.

You can set it in the Cell/Node Default SSL Settings:

Or for a scope, like Cell, Node, or Server:

Or you can set it based on the destination you're connecting to:




回答2:


The JSSE will handle getting the client side certificate and sending it to the server in the handshake. That is as long as the server side of the communication has client authentication enabled or supported and the client side has a key to send. So in your server's SSL configuration is clientAuthentication or clientAuthenticationSupported enabled? From the console you will see the setting on the Quality of Protection panel link from the SSL configuration panel.



来源:https://stackoverflow.com/questions/45758193/is-there-a-way-that-i-can-do-mutual-ssl-without-direct-acces-to-the-websphere-ke

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!