IBM MQ8.0 - AMQ9503 通道协商失败

Kri*_*hna 5 java ssl-certificate ibm-mq

在客户端通道 (SVRCONN) 上启用 SSL 时,我在从 Java 客户端连接到 IBM MQ8.0 时遇到问题。当在通道上禁用 SSL(SSLAUTH 到 OPTIONAL)时,流程工作正常。

客户端是带有 JRE1.7 的 java。MQ 服务器版本为 IBM MQ8.0

创建自签名证书并根据 MQ 设置参考正确交换。

javax.net.debug=ssl 选项在日志中确认证书交换和 SSL 握手成功。

但是当 java 客户端代码试图获取 MQManager 对象时,抛出 MQ 异常。

com.ibm.mq.MQException: MQJE001: Completion code '2', reason '2059' ...

caused by: com.ibm.jmqi.JmqiException: CC=2;RC=2059;AMQ9204: Connection to host '1.2.3.4(1414)' rejected. [1=com.ibm.jmqi.JmqiException[CC=2;RC=2059;AMQ9503: Channel negotiation failed. [3=CHANNEL.SVRCONN.SSL]],3=1.2.3.4(1414), 5=RemoteConnection.analyseSegment] ...

caused by: com.ibm.jmqi.JmqiException: CC=2;RC=2059;AMQ9503: Channel negotiation failed. [3=CHANNEL.SVRCONN.SSL]
Run Code Online (Sandbox Code Playgroud)

我已配置为在客户端和 MQ 客户端通道 (SVRCONN) 中使用 TLS_RSA_WITH_AES_256_CBC_SHA256 作为密码规范。
尝试使用其他密码规范,如 TLS_RSA_WITH_AES_128_CBC_SHA,错误仍然相同。


MQ server error log has AMQ9665: SSL connection closed by remote end of channel '????'  

Explanation: The SSL or TLS connection was closed by the remote host '5.6.7.8' during the secure socket handshake. The channel is '????', in some cases its name can not be determined and so is shown as '????'. The chanel didn't start. 

ACTION: Check the remote end of for SSL and TLS errors. Fix them and restart the channel. 
Run Code Online (Sandbox Code Playgroud)

但是远程端,我只有使用 MQ 库连接到 MQ 服务器的 Java 客户端。


SSLLog 第 4 页 SSLLog 第 5 页

无法从服务器获取数据,因此添加了 SSL 日志中最后 2 页的图像。

上面已经给出了 MQ 服务器端日志。还有一个默认日志 AMQ9999: Channel '????' 到主机 1.2.3.4 异常结束。重复记录相同的错误。没有找到其他日志。


MQ 客户端代码片段如下。

void connect2MQ()
{
    MQEnvironment.hostname=1.2.3.4
    MQEnvironment.port=1414
    MQEnvironment.channel=CLIENT.SVRCONN.SSL
    if(SSLEnabled.equals("Y") // It is set to 'Y' in main method
    {
        MQEnvironment.sslCipherSuit="TLS_RSA_WITH_AES_128_CBC_SHA";
        System.setProperty("javax.net.ssl.truststore","trustStoreCertFilePath");
        System.setProperty("javax.net.ssl.keyStore","keyStoreCertFilePath");
        System.setProperty("javax.net.ssl.trustStorePassword","Pass");
        System.setProperty("javax.net.ssl.keyStorePassword","Pass");
        System.setProperty("javax.net.ssl.trustStoreType","JKS");
        System.setProperty("javax.net.ssl.keyStoreType","JKS");
    }

    try {
        MQQueueManager qmgr = new MQQueueManager("QMGR.TEST.SSL"); // Exception is thrown from here
        ...
    }
Run Code Online (Sandbox Code Playgroud)

Jos*_*hMc 3

您似乎遇到了 APAR IT10837中描述的问题。此问题在 8.0.0.5 及更高版本的 Java MQ 类和 JMS 客户端 jar 文件的 MQ 类中已修复,我建议迁移到 8.0.0.7,这是最新的 v8 版本。

错误消息不匹配,但它使用SSLCAUTH(OPTIONAL)和不使用的症状SSLCAUTH(REQUIRED)与您正在运行的没有修复的版本相匹配。


Tom Leend 有一个 IBM DeveloperWorks MQdev 博客,标题为“ MQ Java、TLS Ciphers、Non-IBM JRE 和 APAR IT06775、IV66840、IT09423、IT10837 -- 请帮帮我!”,其中描述了如果您不具备以下级别的解决方法: MQ 已修复。

---- Code Snippet Start ----
KeyStore keyStore = KeyStore.getInstance("JKS");
java.io.FileInputStream keyStoreInputStream = new java.io.FileInputStream("/home/tom/myKeyStore.jks");
keyStore.load (keyStoreInputStream, password_char_array);

KeyStore trustStore trustStore = KeyStore.getInstance ("JKS");
java.io.FileInputStream trustStoreInputStream = new java.io.FileInputStream("/home/tom/myTrustStore.jks");
trustStore.load (trustStoreInputStream, password_char_array);

keyStoreInputStream.close();
trustStoreInputStream.close();

KeyManagerFactory keyManagerFactory = 
  KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
TrustManagerFactory trustManagerFactory = 
  TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore,password);
trustManagerFactory.init(trustStore);

SSLContext sslContext = SSLContext.getInstance("TLSv1"); 
sslContext.init(keyManagerFactory.getKeyManagers(), 
  trustManagerFactory.getTrustManagers(), 
  null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); 

// classes for JMS
//myJmsConnectionFactory.setObjectProperty(
//  WMQConstants.WMQ_SSL_SOCKET_FACTORY, sslSocketFactory);

// classes for Java
MQEnvironment.sslSocketFactory = sslSocketFactory;
---- Code Snippet End ----
Run Code Online (Sandbox Code Playgroud)