Подключение к WebSphere MQ в Java с помощью SSL / Keystore

Я хотел бы подключиться к Websphere 6.0 MQ через Java. У меня уже работает код для «нормальной» очереди, но теперь мне нужно получить доступ к новой очереди, которая зашифрована SSL (keystore). Мне был отправлен файл под названием something.jks, который, как я полагаю, является сертификатом, который мне нужно хранить где-то. Я искал сеть, но я не могу найти правильную информацию.

Это код, который я использую для «нормальной» очереди. Я предполагаю, что мне нужно установить некоторое свойство, но не знаю, какой из них.

MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory(); connectionFactory.setChannel(channel_); connectionFactory.setHostName(hostname_); connectionFactory.setPort(port_); connectionFactory.setQueueManager(queueManager_); connectionFactory.setTransportType(1); connectionFactory.setSSsetSSLCertStores(arg0) Connection connection = connectionFactory.createConnection(); connection.setExceptionListener(this); session_ = connection.createSession(DEFAULT_TRANSACTED, DEFAULT_ACKMODE); connection.start(); javax.jms.Queue fQueue = session_.createQueue(queue_); consumer = session_.createConsumer(fQueue); 

Учебник Alex Fehners в developerWorks немного устарел (2005), но имеет образцы кода, которые должны работать для вас.

Конфигурация SSL для клиента WebSphere MQ Java / JMS

Ваше Java-приложение будет аутентифицировать QMgr на основе своего сертификата. Это означает, что предоставленный вами файл jks должен иметь либо самозаверяющий сертификат QMgr, либо иметь корневой сертификат центра сертификации, который подписал сертификат QMgr. В любом случае вы указываете файл, используя -Djavax.net.ssl.trustStore= как указано в статье, приведенной выше. Если у jks есть пароль, вам нужно будет указать -Djavax.net.ssl.trustStorePassword= . Аутентификация QMgr с доверительным магазином всегда требуется. Следующая часть может потребоваться или не потребоваться.

Другая часть головоломки заключается в том, что QMgr может потребовать, чтобы ваше приложение выдало сертификат. Другими словами, сертификат QMgr всегда аутентифицирован, независимо от того, требуется ли приложение для аутентификации, является необязательным. Если это так, то у вас есть так называемая «взаимная аутентификация». Если канал, к которому вы подключаетесь, был настроен с помощью SSLCAUTH(REQUIRED) тогда было включено взаимное аутентификация, и QMgr должен иметь самозаверяющий сертификат вашего приложения или корневой сертификат CA, который подписал сертификат вашего приложения в хранилище ключей. Надеюсь, кто-то, кто настроил ваш файл jks, устраивает это уже.

Предполагая, что требуется взаимная аутентификация, ваши юки будут, помимо доверенного сертификата QMgr, частным сертификатом, представляющим ваше приложение. Чтобы получить приложение для получения сертификата и представить его в QMgr, вы используете параметры -Djavax.net.ssl.keyStore= и -Djavax.net.ssl.keyStorePassword= . Обратите внимание, что они говорят, что хранилище ключей, тогда как предыдущие пармы сказали, что хранилище доверия .

Моя рекомендация – работать с администратором WMQ для настройки и проверки SSL-соединения. Первой фазой должно быть тестирование канала с помощью SSLCAUTH(OPTIONAL) . Это подтверждает, что приложение может разрешать и проверять подлинность сертификата QMgr. Только когда вы получите эту работу, администратор SSLCAUTH(REQUIRED) затем изменит канал на SSLCAUTH(REQUIRED) который проверяет аутентификацию в обратном направлении.

Я настоятельно рекомендую вам использовать клиент WMQ v7 для нового приложения. Это происходит по двум причинам: 1) v6 – конец жизни по состоянию на сентябрь 2011 года; 2) код v7 имеет гораздо больше возможностей для диагностики. Клиентский код v7 полностью совместим с v6 QMgr и работает как клиент v6. Вы просто не получаете функциональность v7. Загрузите код клиента WMQ здесь:

IBM – MQC7: клиенты WebSphere MQ V7.0

В этом году я запускаю Лабораторию безопасности в режиме WMQ в IMPACT и выставляю сценарии и руководство по работе с лабораторией в выходные дни по адресу http://t-rob.net, чтобы проверить на это.

Использование SSL из JVM Oracle (JSSE)

См. Также « Что поддерживает TLS cipherspecs / ciphersuites при подключении от Oracle Java (не IBM JRE) к менеджеру очереди MQ? »

В MQ Client версии 8.0.0.2 включен патч для использования TLS с Oracle JVM, это работает с ответом на полосы выше

Получите это для работы, вам понадобится последний клиент MQ, содержащий IV66840 : WMQ V7 JAVA / JMS: ПОДДЕРЖИВАЙТЕ ПОДДЕРЖКУ ДЛЯ ВЫБРАННЫХ ПОЛЬЗОВАТЕЛЕЙ TLS CIPHERSPECS, КОГДА РАБОТАЕТ В ОКРУЖАЮЩЕЙ СРЕДЕ JAVA RUNTIME
http://www-01.ibm.com/support/docview.wss?uid=swg1IV66840
( скачать )

В зависимости от вашего местоположения вам также может потребоваться установить Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8 ( скачать )

Чтобы использовать это, вы должны настроить с помощью аргумента JVM:

  -Dcom.ibm.mq.cfg.useIBMCipherMappings=false 

Обратите внимание, что поведение реализации безопасности по умолчанию отличается от JVM от Oracle и IBM:

Справочное руководство Oracle JSSE гласит:

Если параметр KeyManager [] равен NULL, для этого контекста будет определен пустой KeyManager.

Справочное руководство IBM JSSE гласит:

Если параметр KeyManager [] равен NULL, то установленным поставщикам безопасности будет поиск наивысшей приоритетности реализации KeyManagerFactory, из которой будет получен соответствующий KeyManager.

Это означает, что вам нужно настроить собственный контекст ssl

 SSLContext sslcontext = SSLContext.getInstance("TLS"); String keyStore = System.getProperty("javax.net.ssl.keyStore"); String keyStoreType = System.getProperty("javax.net.ssl.keyStoreType", KeyStore.getDefaultType()); String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword",""); KeyManager[] kms = null; if (keyStore != null) { KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); KeyStore ks = KeyStore.getInstance(keyStoreType); if (keyStore != null && !keyStore.equals("NONE")) { fs = new FileInputStream(keyStore); ks.load(fs, keyStorePassword.toCharArray()); if (fs != null) fs.close(); char[] password = null; if (keyStorePassword.length() > 0) password = keyStorePassword.toCharArray(); kmf.init(ks,password); kms = kmf.getKeyManagers(); } sslcontext.init(kms,null,null); 

А затем поставьте это клиенту MQ JMS:

  JmsConnectionFactory cf = ... MQConnectionFactory mqcf = (MQConnectionFactory) cf; mqcf.setSSLSocketFactory(sslcontext.getSocketFactory()); 

Если вы используете сервер приложений, это может обрабатываться вашим сервером приложений.

Попробуйте этот код вместе с пояснениями T.Robs о сертификате:

 import com.ibm.mq.jms.*; import java.io.FileInputStream; import java.io.Console; import java.security.*; import javax.jms.JMSException; import javax.jms.QueueConnection; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; import com.ibm.mq.jms.MQQueueConnectionFactory; public class SSLTest { public static void main(String[] args) { System.out.println(System.getProperty("java.home")); String HOSTNAME = "myhost"; String QMGRNAME = "MyQMGR"; String CHANNEL = "MY.SVRCONN"; String SSLCIPHERSUITE = "TLS_RSA_WITH_AES_256_CBC_SHA"; try { Class.forName("com.sun.net.ssl.internal.ssl.Provider"); System.out.println("JSSE is installed correctly!"); Console console = System.console(); char[] KSPW = console.readPassword("Enter keystore password: "); // instantiate a KeyStore with type JKS KeyStore ks = KeyStore.getInstance("JKS"); // load the contents of the KeyStore ks.load(new FileInputStream("/home/hudo/hugo.jks"), KSPW); System.out.println("Number of keys on JKS: " + Integer.toString(ks.size())); // Create a keystore object for the truststore KeyStore trustStore = KeyStore.getInstance("JKS"); // Open our file and read the truststore (no password) trustStore.load(new FileInputStream("/home/xwgztu2/xwgztu2.jks"), null); // Create a default trust and key manager TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); // Initialise the managers trustManagerFactory.init(trustStore); keyManagerFactory.init(ks,KSPW); // Get an SSL context. // Note: not all providers support all CipherSuites. But the // "SSL_RSA_WITH_3DES_EDE_CBC_SHA" CipherSuite is supported on both SunJSSE // and IBMJSSE2 providers // Accessing available algorithm/protocol in the SunJSSE provider // see http://java.sun.com/javase/6/docs/technotes/guides/security/SunProviders.html SSLContext sslContext = SSLContext.getInstance("SSLv3"); // Acessing available algorithm/protocol in the IBMJSSE2 provider // see http://www.ibm.com/developerworks/java/jdk/security/142/secguides/jsse2docs/JSSE2RefGuide.html // SSLContext sslContext = SSLContext.getInstance("SSL_TLS"); System.out.println("SSLContext provider: " + sslContext.getProvider().toString()); // Initialise our SSL context from the key/trust managers sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); // Get an SSLSocketFactory to pass to WMQ SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); // Create default MQ connection factory MQQueueConnectionFactory factory = new MQQueueConnectionFactory(); // Customize the factory factory.setSSLSocketFactory(sslSocketFactory); // Use javac SSLTest.java -Xlint:deprecation factory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP); factory.setQueueManager(QMGRNAME); factory.setHostName(HOSTNAME); factory.setChannel(CHANNEL); factory.setPort(1414); factory.setSSLFipsRequired(false); factory.setSSLCipherSuite(SSLCIPHERSUITE); QueueConnection connection = null; connection = factory.createQueueConnection("",""); //empty user, pass to avoid MQJMS2013 messages connection.start(); System.out.println("JMS SSL client connection started!"); connection.close(); } catch (JMSException ex) { ex.printStackTrace(); } catch (Exception ex){ ex.printStackTrace(); } } } 

Помните, какую JRE вы используете. У нас были большие проблемы с использованием Sun JDK из-за определенной криптографии (TLS_RSA_WITH_AES_128_CBC_SHA) на канале SSL в IBM MQ. Мы использовали X509 certeficate. Чтобы получить работу, мы используем IBM JRE, потому что она имеет гораздо большую поддержку некоторых наборов шифров!

  • Исключение SSLHandshake при подключении к сайту https
  • Заставить браузер загружать «https» версию веб-сайта, а не «http»?
  • Использование CERT Tapioca на VM
  • Безопасна ли строка запроса HTTPS?
  • Проверка подлинности клиента HTTPS на Java
  • Почему OS X не доверяет SSL-сертификату GitHub?
  • Force SSL / HTTPS с mod_rewrite
  • Тип Keystore: какой из них использовать?
  • Использовать самоподписанный сертификат cURL?
  • Javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL-квитирование отменено: ошибка в библиотеке SSL, обычно ошибка протокола
  • Как сделать HTTPS POST с Android?
  • Давайте будем гением компьютера.