2010-04-22 14 views
12

Tôi muốn kết nối với Websphere 6.0 MQ qua Java. Tôi đã làm việc mã cho một hàng đợi "bình thường", nhưng bây giờ tôi cần phải truy cập vào một hàng đợi mới được mã hóa SSL (keystore). Tôi đã được gửi một tập tin gọi là something.jks, mà tôi giả định là một chứng chỉ tôi cần lưu trữ ở đâu đó. Tôi đã tìm kiếm trên mạng, nhưng tôi không thể tìm thấy thông tin phù hợp.Kết nối với Websphere MQ bằng Java với SSL/Keystore

Đây là mã tôi sử dụng cho hàng đợi "bình thường". Tôi cho rằng tôi cần thiết lập một số tài sản, nhưng không chắc chắn cái nào.

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

Trả lời

10

Hướng dẫn về Fehners trên developerWorks cũ một chút (2005) nhưng có các mẫu mã sẽ phù hợp với bạn.

SSL configuration of the Websphere MQ Java/JMS client

ứng dụng Java của bạn sẽ xác thực QMgr dựa trên giấy chứng nhận của nó. Điều đó có nghĩa là tệp jks bạn đã cung cấp phải có chứng chỉ tự ký của QMgr hoặc nó sẽ có chứng chỉ gốc của một Tổ chức phát hành chứng chỉ đã ký chứng chỉ QMgr. Trong cả hai trường hợp, bạn trỏ đến tệp bằng cách sử dụng -Djavax.net.ssl.trustStore=<location of trustStore> như được lưu ý trong bài viết được liên kết ở trên. Nếu jks có mật khẩu, bạn cũng cần phải chỉ định -Djavax.net.ssl.trustStorePassword=<password>. Việc xác thực QMgr với một truststore là luôn yêu cầu. Phần tiếp theo có thể hoặc có thể không được yêu cầu.

Một phần khác của câu đố là QMgr có thể yêu cầu ứng dụng của bạn xuất trình chứng chỉ. Nói cách khác, chứng chỉ QMgr là luôn được xác thực, cho dù ứng dụng được yêu cầu xác thực là tùy chọn hay không. Nếu đó là sau đó bạn có những gì được gọi là "xác thực lẫn nhau". Nếu kênh mà bạn kết nối với đã được cấu hình với SSLCAUTH(REQUIRED) thì xác thực lẫn nhau đã được bật và QMgr phải có chứng chỉ tự ký của ứng dụng hoặc chứng chỉ gốc CA đã ký chứng chỉ ứng dụng của bạn trong kho khóa. Hy vọng rằng bất cứ ai thiết lập tập tin jks của bạn sẽ có sắp xếp cho điều này rồi.

Giả sử xác thực lẫn nhau là bắt buộc, khi đó, jks của bạn sẽ có, ngoài chứng chỉ đáng tin cậy của QMgr, chứng chỉ cá nhân đại diện cho đơn đăng ký của bạn. Để ứng dụng tìm nạp cert và đưa nó vào QMgr, bạn sử dụng các tham số -Djavax.net.ssl.keyStore=<location of keyStore>-Djavax.net.ssl.keyStorePassword=<password>. Lưu ý rằng các cửa hàng khóa trong khi các parm trước đó cho biết tin cậy cửa hàng.

Đề xuất của tôi là làm việc với quản trị viên WMQ để thiết lập và kiểm tra kết nối SSL. Giai đoạn đầu tiên cần kiểm tra kênh với SSLCAUTH(OPTIONAL). Điều này xác minh rằng ứng dụng có thể giải quyết và xác thực chứng chỉ của QMgr. Chỉ khi bạn nhận được công việc này thì quản trị viên WMQ sẽ thay đổi kênh thành SSLCAUTH(REQUIRED) để kiểm tra xác thực theo hướng ngược lại.

Tôi sẽ cao khuyên bạn nên sử dụng ứng dụng WMQ v7 cho ứng dụng mới. Đây là vì hai lý do: 1) v6 là cuối đời kể từ tháng 9 năm 2011; 2) mã v7 có khả năng chẩn đoán nhiều hơn được tích hợp. Mã máy khách v7 hoàn toàn tương thích với v6 QMgr và hoạt động giống như máy khách v6. Bạn chỉ không nhận được chức năng v7. Tải về mã khách hàng WMQ miễn phí tại đây:

IBM - MQC7: WebSphere MQ V7.0 Clients

Tôi đang chạy Security Lab WMQ Hands-On tại IMPACT trong năm nay và sẽ được đăng tải hướng dẫn kịch bản và phòng thí nghiệm cuối tuần qua tại http://t-rob.net nên kiểm tra lại cho cái đó.

3

Hãy nhận biết bạn đang sử dụng JRE nào. Chúng tôi đã gặp rắc rối lớn khi sử dụng Sun JDK, vì một sự mã hóa nào đó (TLS_RSA_WITH_AES_128_CBC_SHA) trên kênh SSL tới IBM MQ. Chúng tôi đã sử dụng chứng nhận X509. Để làm cho nó hoạt động, chúng tôi đang sử dụng IBM JRE vì nó có sự hỗ trợ lớn hơn cho một số bộ mã hóa nhất định!

+0

Tôi cũng đang đối mặt với việc không thể kết nối với "TLS_RSA_WITH_AES_128_CBC_SHA", Vẫn không có giải pháp để làm cho nó hoạt động liền mạch với Sun JDK? –

3

Hãy thử mã này cùng với T.Robs giải thích về chứng chỉ:

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

Sử dụng SSL từ Oracle JVM (JSSE)

Xem thêm "What TLS cipherspecs/ciphersuites are supported when connecting from Oracle Java (non-IBM JRE) to MQ queue manager?"

Trong MQ phiên bản khách hàng 8.0.0.2 có một bản vá được bao gồm để sử dụng TLS với Oracle JVM, điều này làm việc với lanes câu trả lời ở trên

Địa lý t này để làm việc, bạn sẽ cần Client MQ mới nhất có chứa IV66840: WMQ V7 JAVA/JMS: ADD HỖ TRỢ CHO CHỌN TLS CIPHERSPECS KHI CHẠY TRÊN KHÔNG IBM Java Runtime Environment
http://www-01.ibm.com/support/docview.wss?uid=swg1IV66840
(download)

tùy thuộc vào vị trí của bạn, bạn cũng có thể cần phải cài đặt Java Cryptography Extension (JCE) Chính sách Unlimited Strength Thẩm quyền tập tin 8 (download)

để sử dụng này, bạn phải cấu hình bằng cách sử dụng đối số JVM:

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

Lưu ý rằng việc thực hiện bảo mật mặc định hành vi differs giữa Oracle và IBM JVM:

Các Oracle JSSE Reference guide nói:

Nếu KeyManager [] tham số là null, sau đó một KeyManager trống sẽ được được định nghĩa cho ngữ cảnh này.

Các IBM JSSE Reference guide nói:

Nếu KeyManager [] paramater là null, an ninh được cài đặt các nhà cung cấp sẽ được tìm kiếm để thực hiện ưu tiên cao nhất của các KeyManagerFactory, từ đó một KeyManager thích hợp sẽ được thu được.

Điều đó có nghĩa rằng bạn phải thiết lập 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); 

Và sau đó cung cấp mà cho khách hàng MQ JMS:

JmsConnectionFactory cf = ...                  

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

Nếu sử dụng một máy chủ ứng dụng này có thể được xử lý bởi ứng dụng của bạn máy chủ.

+0

Theo hiểu biết của tôi, chúng tôi sử dụng ssl bằng cách chỉ định các thuộc tính java chuẩn Ví dụ: javax.net.ssl.trustStore. hoặc bằng cách tạo SSLSocketFactory. Nếu tôi đang sử dụng các thuộc tính tiêu chuẩn như được đề cập trong http://www.ibm.com/developerworks/websphere/library/techarticles/0510_fehners/0510_fehners.html Tôi vẫn cần phải nâng cấp lên các phiên bản như đã đề cập ở trên? –

+0

@AnujKhandelwal bạn có gặp vấn đề gì không? Các mật mã reqires cấu hình được liệt kê trong IV66840 liên kết ở trên, xem http://disablessl3.com/ – oluies