Подключение к Websphere MQ в Java с помощью SSL / Keystore - PullRequest
14 голосов
/ 22 апреля 2010

Я бы хотел подключиться к Websphere 6.0 MQ через Java. У меня уже есть рабочий код для «нормальной» очереди, но теперь мне нужно получить доступ к новой очереди с шифрованием SSL (хранилище ключей). Мне прислали файл с именем some.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);

Ответы [ 4 ]

12 голосов
/ 23 апреля 2010

Учебное пособие Алекса Фенерса в developerWorks несколько устарело (2005 г.), но содержит примеры кода, которые должны работать на вас.

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

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

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

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

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

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

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

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

8 голосов
/ 06 апреля 2015

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

См. Также « Какие шифровальные спецификации / наборы шифров TLS поддерживаются при подключении из Oracle Java (не IBM JRE) к MQ queue manager? »

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

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

В зависимости от вашего местоположения вам также может понадобиться установить Расширение Java Cryptography Extension (JCE) Файлы политики неограниченной юрисдикции 8 ( скачать )

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

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

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

Справочное руководство 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());  

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

4 голосов
/ 18 сентября 2014

Попробуйте этот код вместе с пояснениями 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();
      }
   }
}
3 голосов
/ 16 июля 2011

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

...