2010-04-22 23 views
12

mi piacerebbe di connettersi a un Websphere MQ 6.0 tramite Java. Ho già lavorato codice per una coda "normale", ma ora ho bisogno di accedere a una nuova coda che è crittografata SSL (keystore). Mi è stato inviato un file chiamato something.jks, che presumo sia un certificato che ho bisogno di memorizzare da qualche parte. Ho cercato la rete, ma non riesco a trovare le informazioni giuste.Collegamento ad un Websphere MQ in Java con SSL/Keystore

Questo è il codice che uso per la coda "normale". Presumo che ho bisogno di impostare alcune proprietà, ma non sono sicuro quale.

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); 

risposta

10

Il tutorial di Alex Fehners in developerWorks è un po 'vecchio (2005) ma contiene degli esempi di codice che dovrebbero funzionare per voi.

SSL configuration of the Websphere MQ Java/JMS client

La vostra applicazione Java autenticherà la QMgr in base al suo certificato. Ciò significa che il file jks che ti è stato fornito deve avere il certificato autofirmato di QMgr o avrà il certificato di origine di un'autorità di certificazione che ha firmato il certificato di QMgr. In entrambi i casi, si punta al file usando lo -Djavax.net.ssl.trustStore=<location of trustStore> come indicato nell'articolo collegato sopra. Se i jks hanno una password, sarà necessario specificare anche -Djavax.net.ssl.trustStorePassword=<password>. L'autenticazione di QMgr con un truststore è sempre obbligatoria. La prossima parte può o non può essere richiesta.

L'altro pezzo del puzzle è che il QMgr può richiedere la vostra applicazione di presentare un certificato. In altre parole, il certificato QMgr è sempre autenticato, se l'applicazione è richiesta per l'autenticazione è facoltativa. Se è così, hai ciò che è noto come "autenticazione reciproca". Se il canale a cui ci si connette è stato configurato con SSLCAUTH(REQUIRED), l'autorizzazione reciproca è stata abilitata e il QMgr deve avere il certificato autofirmato dell'applicazione o un certificato radice CA che ha firmato il certificato della propria app nel proprio keystore. Spero che chiunque abbia creato il file jks lo abbia già organizzato.

Supponendo autenticazione reciproca è necessaria, quindi i vostri JKS avranno, oltre al CERT di fiducia del QMgr, un CERT privata che rappresenta l'applicazione. Per ottenere l'app per recuperare il certificato e presentarlo a QMgr, utilizzare i parametri -Djavax.net.ssl.keyStore=<location of keyStore> e -Djavax.net.ssl.keyStorePassword=<password>. Nota questi dicono chiave negozio mentre i parms precedenti detto fiducia negozio.

La mia raccomandazione è quella di lavorare con l'amministratore WMQ per impostare e verificare la connessione SSL. La prima fase dovrebbe essere testare il canale con SSLCAUTH(OPTIONAL). Ciò verifica che l'applicazione possa risolvere e autenticare il certificato di QMgr. Solo quando questo funziona, l'amministratore di WMQ modificherà il canale su SSLCAUTH(REQUIRED) che verifica l'autenticazione nella direzione opposta.

Vorrei altamente consigliare di utilizzare il client v7 WMQ per una nuova applicazione. Questo è per due motivi: 1) v6 è la fine della vita a partire da settembre 2011; 2) il codice v7 ha molte più funzionalità diagnostiche integrate. Il codice client v7 è completamente compatibile con un QMgr v6 e funziona come il client v6. Semplicemente non ottieni la funzionalità v7. Scarica il codice del client WMQ gratuitamente qui:

IBM - MQC7: WebSphere MQ V7.0 Clients

sto correndo il WMQ Hands-On Lab di sicurezza al momento dell'impatto di quest'anno e sarà la pubblicazione della guida script e di laboratorio durante il fine settimana a http://t-rob.net quindi torna per quella.

3

Essere consapevoli di quale JRE si sta utilizzando. Abbiamo avuto grossi problemi nell'utilizzo di Sun JDK, a causa di una determinata crittografia (TLS_RSA_WITH_AES_128_CBC_SHA) sul canale SSL per IBM MQ. Abbiamo usato un Xficity X509. Per farlo funzionare usiamo IBM JRE perché ha un supporto molto più grande per alcune suite di cifratura!

+0

Anche io non sono in grado di connettermi con "TLS_RSA_WITH_AES_128_CBC_SHA", non esiste ancora alcuna soluzione per farlo funzionare perfettamente con Sun JDK? –

3

Prova questo codice con T.Robs spiegazioni sul certificato:

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(); 
     } 
    } 
} 
6

Utilizzando SSL dal Oracle JVM (JSSE)

Vedi anche

In MQ Client versione "What TLS cipherspecs/ciphersuites are supported when connecting from Oracle Java (non-IBM JRE) to MQ queue manager?" 8.0.0.2 è inclusa una patch per utilizzare TLS con Oracle JVM, questo funziona con la risposta lanes sopra

Il ge t farlo funzionare è necessario l'ultimo client MQ che contiene IV66840: WMQ V7 Java/JMS: aggiungere il supporto per particolari TLS CIPHERSPECS QUANDO in esecuzione con IBM Java Runtime Environment
http://www-01.ibm.com/support/docview.wss?uid=swg1IV66840
(download)

a seconda della posizione potrebbe essere necessario installare (Java Cryptography Extension JCE) Politica forza illimitata Giurisdizione Files 8 (download)

per utilizzare questo è necessario configurato utilizzando l'argomento JVM:

01.235.164,106174 millions
-Dcom.ibm.mq.cfg.useIBMCipherMappings=false 

Nota che il comportamento implementazione di protezione predefinito differs tra Oracle e IBM JVM:

Il Oracle JSSE Reference guide dice:

Se il parametro KeyManager [] è nullo, allora un KeyManager vuoto sarà essere definito per questo contesto.

Il IBM JSSE Reference guide dice:

Se il KeyManager [] paramater è nullo, la sicurezza installato fornitori verranno ricercati per la realizzazione più alta priorità del KeyManagerFactory, da cui un KeyManager appropriata essere ottenuto .

Il che significa che si deve configurare your own ssl context

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); 

E poi fornitura che al client MQ JMS:

JmsConnectionFactory cf = ...                  

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

Se si utilizza un server applicazioni questo potrebbe essere gestito dall'applicazione server.

+0

Secondo la mia comprensione, usiamo ssl specificando le proprietà java standard, ad es. javax.net.ssl.trustStore. o creando SSLSocketFactory. Se sto usando le proprietà standard come menzionato in http://www.ibm.com/developerworks/websphere/library/techarticles/0510_fehners/0510_fehners.html Devo ancora eseguire l'aggiornamento alle versioni come menzionato sopra? –

+0

@AnujKhandelwal hai qualche problema con qualcosa? I codici che richiedono la configurazione sono elencati in IV66840 linkati sopra, vedere http://disablessl3.com/ – oluies

Problemi correlati