Есть ли способ сделать Mutual SSL без прямого доступа к хранилищу ключей Websphere в Java?

Я пытаюсь установить взаимный SSL между двумя серверами Websphere 8.5.5. Я просто назову их ServerA и ServerB.

ServerA: клиентская сторона, SSL-сертификат ServerB добавлен в DefaultTrustKeyStore.

ServerB: на стороне сервера добавлен SSL-сертификат ServerA в DefaultTrustKeyStore. Я также установил WAR, который предоставляет сервлет, который может получать сообщение HTTP POST, регистрировать его и отвечать «ОК» клиенту. Режим аутентификации клиента установлен на «Обязательный».

Теперь у меня возникла проблема: традиционный способ клиентской части Mutual SSL ДОЛЖЕН читать хранилище ключей напрямую, чтобы получить закрытый ключ, поэтому мы можем использовать его, чтобы настроить наш SSLContext для аутентификации клиента. Но у него может быть недостаток безопасности для прямого доступа к хранилищу ключей. Поэтому мне нужно найти способ, могу ли я позволить моей веб-сфере ServerA сделать это за меня (или код Java, который может дать команду Websphere сделать это).

Может ли кто-нибудь научить меня, как это сделать без прямого доступа к хранилищу ключей, пожалуйста?


ОБНОВИТЬ:

Привет дбро.

Я попробовал ваш способ сделать петлевое соединение, но похоже, что оно не работает.

Вот последний раздел журнала отладки 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

Я использую DefaultKeyStores, созданные WAS. Поскольку страница динамической исходящей конечной точки продолжает выдавать мне ошибку CWPKI0681E, поэтому я применил ваш первый способ.

Это работает на вашем? или это потому, что я использую ЦС по умолчанию, созданный WAS?


ОБНОВЛЕНИЕ 6 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. Не могли бы вы подробнее описать, как вы этого добились? @Ален @dbreaux


person Kaninchen    schedule 18.08.2017    source источник
comment
Если вы не можете получить доступ к своему собственному хранилищу ключей, вы не можете быть аутентифицирующим узлом SSL. Какой недостаток безопасности?   -  person user207421    schedule 21.08.2017
comment
Поскольку вам нужно получить к нему доступ, вы должны записать путь к хранилищу ключей и пароль где-то внутри программы (или в файле). Так что моему работодателю это не нравится   -  person Kaninchen    schedule 22.08.2017
comment
WebSphere должен быть в состоянии автоматически представить вам ваш клиентский сертификат, без необходимости явно ссылаться на хранилище ключей или закрытый ключ. Это не работает, или вы еще не пробовали?   -  person dbreaux    schedule 24.08.2017
comment
@dbreaux эта часть предназначена для тех случаев, когда вы играете роль Сервера. Но мне нужно сделать это, когда я клиент   -  person Kaninchen    schedule 24.08.2017
comment
Нет, это также, когда вы клиент, работающий под WAS. Вы пробовали это, и это не сработало? В этом случае я начал ответ, который объясняет, где вам, возможно, придется указать, какой сертификат клиента представить. Или вы еще даже не пробовали, потому что не ожидали, что это сработает?   -  person dbreaux    schedule 24.08.2017
comment
Я уже пробовал, но это не сработало. настройки такие же, как в моем посте. Мое приложение, установленное на WAS ServerA, пыталось отправить HTTP POST на ServerB, но это просто не удалось.   -  person Kaninchen    schedule 24.08.2017
comment
Если я отключу одноранговую аутентификацию ServerB, все пойдет гладко   -  person Kaninchen    schedule 24.08.2017
comment
Хорошо, я собираюсь опубликовать свой ответ на случай, если он будет полезен вам или кому-то, кто придет позже. Если это не относится к вашей ситуации, прошу прощения.   -  person dbreaux    schedule 25.08.2017


Ответы (2)


Похоже, что в конфигурации WebSphere вам нужно указать сертификат клиента из хранилища ключей, который будет представляться при установлении исходящего соединения. (Честно говоря, я не знаю, можете ли вы отредактировать хранилище ключей, чтобы установить его по умолчанию. Я не вижу способа сделать это из консоли администратора, но вы можете сделать это извне. Или, может быть, он уже установлен, но этого недостаточно)

Но способ, которым вы можете установить это явно, находится в конфигурациях SSL. Я верю, что все эти уровни должны работать, но признаюсь, лично я их не пробовал.

Вы можете установить его в настройках SSL по умолчанию для ячейки/узла:

CellDefaultSSLSSettings

Или для области действия, такой как Cell, Node или Server:

Конфигурации безопасности конечной точки

Конфигурация SSL конечной точки

Или вы можете установить его в зависимости от пункта назначения, к которому вы подключаетесь:

Конфигурация динамического исходящего SSL

person dbreaux    schedule 25.08.2017
comment
занялся другой работой. Я проверю это, когда другой будет готов. - person Kaninchen; 28.08.2017
comment
На стороне сервера вашего общения по-прежнему потребуется включить clientAuthentication или clientAuthenticationSupported. Сторона сервера определяет, будет ли выполняться аутентификация клиента (взаимный SSL). Мне непонятно, сделали вы это или нет. Вы можете найти этот параметр по ссылке «Качество защиты» на панели конфигурации SSL. - person Alaine; 28.08.2017
comment
Я пытался использовать это для обратной связи, но, похоже, это не работает. Это работает на вашем? или это потому, что я использую самоподписанный ЦС, который WAS создал автоматически при его установке? - person Kaninchen; 03.09.2017
comment
Я попробовал аутентификацию клиента SSL, используя сертификат WAS по умолчанию. Чтобы убедиться, что проверка подлинности SSL-клиента зацикливается на себе, мне пришлось запустить с трассировкой, чтобы убедиться, что проверка доверия на стороне сервера выполняется. Если он идет на другой сервер или даже на другую конфигурацию SSL, вы можете делать такие вещи, как добавлять и удалять доверие для проверки. Переход к одной и той же конфигурации SSL с одним сертификатом может быть немного сложным. Какая у вас версия? - person Alaine; 05.09.2017
comment
@Alaine Я использую 8.5.5, но я думаю, что в этой проблеме нет никакой разницы между этим и WAS 9. Кстати, вы успешно подключились к серверу, выполнив аутентификацию на стороне клиента? Думаю, я мог бы найти некоторые подсказки. - person Kaninchen; 06.11.2017
comment
@dbreaux Если вы не возражаете, я тоже хотел бы узнать ваше мнение, если вы знаете, что не так с моим делом. :) - person Kaninchen; 06.11.2017
comment
@Kaninchen Когда вы говорите «подключиться к серверу», вы имеете в виду из консоли или из клиентской программы, например, wsadmin? Только что попробовал с консоли. Аутентификация клиента SSL работает до тех пор, пока я все настраиваю. Мне нужно добавить личный сертификат в браузер и обменяться подписантами между браузером и WAS. Консоль не настроена на вход с сертификатом, но я не думаю, что вы ищете вход с сертификатом, не так ли? - person Alaine; 06.11.2017
comment
@Alaine Нет, вход в систему с сертификатом - это не то, что я ищу. Значит, у вас сработало, когда вы попросили свое приложение WAR или EAR на клиентской стороне WAS подключиться к серверу, требующему аутентификации клиента? Хм... Я начну сначала, чтобы увидеть, какой шаг я пропустил. - person Kaninchen; 07.11.2017
comment
Как я и ожидал... Каким-то образом у моего клиента БЫЛО, что у него нет сертификата, и он распечатал это в журнале Warning: no suitable certificate found - continuing without client authentication - person Kaninchen; 07.11.2017

JSSE будет обрабатывать получение сертификата на стороне клиента и отправку его на сервер при рукопожатии. Это происходит до тех пор, пока на стороне сервера связи включена или поддерживается проверка подлинности клиента, а на стороне клиента есть ключ для отправки. Итак, в конфигурации SSL вашего сервера включена clientAuthentication или clientAuthenticationSupported? В консоли вы увидите настройку по ссылке «Панель качества защиты» из панели конфигурации SSL.

person Alaine    schedule 21.08.2017
comment
Клиент не отправляет ключи, он отправляет сертификат. - person user207421; 21.08.2017
comment
Ваше право, он отправляет сертификат, но он должен быть частью пары на клиенте, прежде чем отправлять его на сервер. - person Alaine; 21.08.2017