Вопрос:
Мы являемся одним из приложений в более крупной среде и клиентом для некоторого интерфейса данных, используя Websphere MQ 8.x. Наше приложение представляет собой приложение Java EE, работающее на WildFly 9, которое использует адаптер ресурсов (wmq.jmsra.rar), который развертывается вместе с файлом EAR в том же AS. Мы взаимодействуем с сервером MQ в обоих направлениях. Таким образом, у нас есть, с одной стороны, некоторые MDB (которые обусловлены историческим происхождением, все еще находящимся в формате EJB 2.x без аннотаций), которые перечислены в некоторых очередях и которые настроены дескриптором развертывания ejb-jar.xml, содержащим свойства конфигурации активации destinationType, channel, queueManager, hostName, username, password. С другой стороны, у нас есть отправитель, который ищет фабрику соединений в очереди и очередь через JNDI и создает соединение.
Теперь у нас есть требование, чтобы новый сервер MQ мог связываться через SSL и сертификат клиента. У нас есть такой сертификат от пользователей сервера для нашей машины. Поэтому мои вопросы:
- Что нужно сделать, чтобы он работал с настройкой, описанной выше?
- Возможно ли это исключительно по конфигурации и, таким образом, прозрачно для приложения или имеет приложение для конкретного использования SSL, представляет сертификат или что-то подобное?
- Связано ли это с любым другим хранилищем ключей, которое уже используется какой-либо другой частью приложения?
- Требуется ли некоторое дополнительное программное обеспечение IBM MQ для его работы? (Наш клиент – это только RAR, не установлено ни одно программное обеспечение, и на нашей стороне не должно быть сервера MQ).
Обновление: я пошел на настройку глобальных свойств JSSE для виртуальной машины, поскольку решил ее проблему как начало.
Необходимо было установить следующие параметры:
-Djavax.net.ssl.trustStore=<location of trustStore> -Djavax.net.ssl.keyStore=<location of keyStore> -Djavax.net.ssl.keyStorePassword=<password>
Кроме того, поскольку я использую виртуальную машину, отличную от IBM, установлен следующий параметр:
-Dcom.ibm.mq.cfg.useIBMCipherMappings=false
Затем необходимо было установить свойство набора шифров в конфигурации RAR в standalone-full.xml вместе с другими параметрами подключения моей установки WildFly:
<resource-adapter id=»wmq.jms.rar»> … <connection-definitions> <connection definition …> <config-property name=»sslCipherSuite»>xxx</config-property> … </resource-adapter»>
И, наконец, MDB, просматривающие очереди, также должны были быть настроены на использование набора шифров, поэтому в моем случае мне пришлось добавить это в ejb-jar.xml, добавив для каждого MDB:
<activation-config-property> <activation-config-property-name>sslCipherSuite</activation-config-property-name> <activation-config-property-value>xxx</activation-config-property-value> <activation-config-property> Лучший ответ:
OP заявили в комментариях, что они используют OpenJDK 8 и используют адаптер ресурсов IBM MQ v9.0.0.1, обе следующие известные проблемы исправлены в этой версии, но помещая эту информацию здесь в интересах других, которые еще не могут быть в выпуске, где они фиксируются:
-
APAR IV66840: TLS cipherspecs в не-IBM JRE не поддерживались до 8.0.0.2.
-
APAR IT10837: WildFly 9 может столкнуться с еще одной проблемой, если использовать JRE для IBM, не содержащую IBM, в поиске KeyStore, который содержит сертификат клиента, это исправлено в 8.0.0.5.
Адаптер ресурсов включает в себя функции MQ для поддержки TLS, но использует базовую JSSE для фактического шифрования.
Основываясь на RFC 5246, он предлагает, чтобы клиент TLS должен был возвращать сертификат, который подходит, на основе сервера, отправляющего “Список выделенных имен [X501] допустимых полномочий_сервера, представленных в формате DER-кодированного”. Это означало бы что если сертификаты в вашем ключевом хранилище для разных целей (например, существующие сертификаты не-MQ и сертификаты MQ) не подписаны одной и той же цепочкой CA, а различные серверы TLS, к которым вы подключаетесь, не принимают сертификаты от CA других сертификатов в вашем хранилище ключей (например, существующие сертификаты без MQ и сертификаты MQ), то JSSE вернет соответствующий сертификат каждому.
Например, если существующие сертификаты не-MQ подписываются внутренним ЦС, а сертификат MQ подписывается другим CA компании, маловероятно, что компания MQ будет доверять вашим внутренним сертификатам CA, наоборот, маловероятно, что ваш другой не-MQ Серверы TLS, к которым вы подключаетесь, будут доверять другим CA компании. Поскольку JSSE вернет только сертификат, которому доверял удаленный сервер, они не должны влиять друг на друга. Вам просто нужно добавить сертификат MQ в существующий магазин ключей.
Цитаты из соответствующих разделов RFC 5246 находятся внизу этой публикации.
@a_cornish_pasty ответ на ваш вопрос ” Использовать конкретное хранилище ключей для JMS ” также является альтернативой, так как это позволит вам указать отдельный хранилище ключей от того, что использует остальная часть Wildfly, этот магазин ключей может иметь ТОЛЬКО сертификат MQ, поэтому никаких шансов вызывая проблему с существующим хранилищем ключей и сертификатами.
В разделе 7.4.4 RFC 5246 указано следующее:
7.4.4. Запрос сертификата
Когда это сообщение будет отправлено:
Неанонимный сервер может дополнительно запросить сертификат у клиента, если это необходимо для выбранного набора шифров. Это сообщение, если оно отправлено, будет немедленно следовать сообщению ServerKeyExchange (если оно отправлено, в противном случае это сообщение следует за сообщением сертификата сервера).
Далее говорится:
certificate_authorities
Список отличительных имен [X501] допустимых сертификатов_сервера, представленных в формате DER. Эти отличительные имена могут указывать требуемое различающееся имя для корневого ЦС или для подчиненного ЦС; таким образом, это сообщение может использоваться для описания известных корней, а также для требуемого пространства авторизации. Если список certificate_authorities пуст, тогда клиент МОЖЕТ отправить любой сертификат соответствующего типа ClientCertificateType, если только не существует какой-либо внешней договоренности об обратном.
RFC 5246 Раздел 7.4.6 гласит следующее:
7.4.6. Сертификат клиента
Когда это сообщение будет отправлено:
Это первое сообщение, которое клиент может отправить после получения сообщения ServerHelloDone. Это сообщение отправляется только в том случае, если сервер запрашивает сертификат. Если подходящий сертификат не доступен, клиент ДОЛЖЕН отправить сообщение сертификата, не содержащее сертификатов. То есть структура certificate_list имеет длину, равную нулю. Если клиент не отправляет сертификаты, сервер МОЖЕТ по своему усмотрению либо продолжить рукопожатие без проверки подлинности клиента, либо ответить фатальным сигналом handshake_failure. Кроме того, если какой-либо аспект цепочки сертификатов был неприемлемым (например, он не был подписан известным, доверенным ЦС), сервер МОЖЕТ по своему усмотрению либо продолжить рукопожатие (учитывая, что клиент не прошел проверку подлинности), либо отправить фатальное предупреждение.
Далее говорится:
- Если список certificate_authorities в сообщении запроса сертификата не был пустым, один из сертификатов в цепочке сертификатов ДОЛЖЕН быть выпущен одним из перечисленных ЦС.