Java経由でWebsphere6.0MQに接続したいのですが。 「通常の」キューのコードはすでに機能していますが、SSL暗号化された新しいキュー(キーストア)にアクセスする必要があります。どこかに保存する必要のある証明書であると思われる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);
DeveloperWorksのAlexFehnersチュートリアルは少し古い(2005)ですが、あなたのために働くはずのコードサンプルがあります。
Websphere MQ Java/JMSクライアントのSSL構成
Javaアプリは、証明書に基づいてQMgrを認証します。つまり、提供されたjksファイルには、QMgrの自己署名証明書が含まれているか、認証局のルート証明書が含まれている必要があります。 QMgrの証明書に署名しました。いずれの場合も、上記のリンク先の記事に記載されているように、_-Djavax.net.ssl.trustStore=<location of trustStore>
_を使用してファイルをポイントします。jksにパスワードがある場合は、_-Djavax.net.ssl.trustStorePassword=<password>
_も指定する必要があります。トラストストアを使用するQMgrは常に必要です。次の部分は必要な場合と不要な場合があります。
パズルのもう1つのピースは、QMgrがアプリに証明書の提示を要求する場合があることです。つまり、QMgr証明書は常に認証され、アプリが認証を必要とするかどうかはオプションです。そうであれば、「相互認証」と呼ばれるものがあります。接続するチャネルがSSLCAUTH(REQUIRED)
で構成されている場合、相互認証が有効になっており、QMgrには、アプリケーションの自己署名証明書またはアプリの証明書に署名したCAルート証明書がキーストアにある必要があります。うまくいけば、あなたのjksファイルを設定した人は誰でもこれをすでに手配しているでしょう。
相互認証が必要であると仮定すると、JKには、QMgrの信頼できる証明書に加えて、アプリケーションを表すプライベート証明書があります。アプリに証明書をフェッチしてQMgrに提示させるには、_-Djavax.net.ssl.keyStore=<location of keyStore>
_パラメーターと_-Djavax.net.ssl.keyStorePassword=<password>
_パラメーターを使用します。これらはkeyストアと言っているのに対し、前のパラメーターはtrustストアと言っていることに注意してください。
WMQ管理者と協力して、SSL接続をセットアップおよびテストすることをお勧めします。最初のフェーズは、SSLCAUTH(OPTIONAL)
を使用してチャネルをテストすることです。これにより、アプリケーションがQMgrの証明書を解決および認証できることが確認されます。これが機能するようになった場合にのみ、WMQ管理者はチャネルをSSLCAUTH(REQUIRED)
に変更し、逆方向の認証をテストします。
強く新しいアプリケーションにはWMQv7クライアントを使用することをお勧めします。これには2つの理由があります。1)v6は2011年9月の時点でサポートが終了しています。 2)v7コードにはさらに多くの診断機能が組み込まれています。v7クライアントコードはv6 QMgrと完全に互換性があり、v6クライアントと同様に機能します。 v7の機能は利用できません。ここからWMQクライアントコードを無料でダウンロードします。
IBM --MQC7:WebSphere MQ V7.0クライアント
私は今年IMPACTでWMQハンズオンセキュリティラボを実行しており、週末にスクリプトとラボガイドを http://t-rob.net に投稿する予定ですので、もう一度確認してください。
Oracle JVM(JSSE)からのSSLの使用
「 Oracle Java(IBM JRE以外)からMQキュー・マネージャーに接続するときにサポートされるTLS暗号仕様/暗号スイート? 」」も参照してください。
MQクライアントバージョン8.0.0.2には、Oracle JVMでTLSを使用するためのパッチが含まれています。これは、上記の レーン の回答で機能します。
これを機能させるには、 IV66840 を含む最新のMQクライアントが必要です。WMQV7Java/JVM:IBM以外で実行する場合の選択されたTLSCIPHERSPECSのサポートの追加Javaランタイム環境
http://www-01.ibm.com/support/docview.wss?uid=swg1IV66840
( ダウンロード )
お住まいの地域によっては、Java Cryptography Extension(JCE)Unlimited Strength Jurisdiction Policy Files 8( download )もインストールする必要がある場合があります。
これを使用するには、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);
そして、それをMQJMSクライアントに提供します。
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に注意してください。 IBM MQへのSSLチャネルで特定の暗号化(TLS_RSA_WITH_AES_128_CBC_SHA)が発生したため、SunJDKの使用に大きな問題が発生しました。 X509証明書を使用しました。それを機能させるために、IBM JREを使用しています。これは、特定の暗号スイートをはるかに大きくサポートしているためです。