IBM MQ云连接

问题描述 投票:0回答:1

我正在尝试按照此https://cloud.ibm.com/docs/mqcloud?topic=mqcloud-mqoc_jms_tls在应用程序和云之间设置ssl / tls。

当在云mq应用程序通道CLOUD.APP.SVRCONN上将sslauth设置为可选时,我就可以发送和接收消息。

ii使用以下命令下载了证书并将其添加到信任存储中。

keytool -importcert -alias DigiCertRootCA -file qmgrcert.pem -keystore truststore.jks

我正在通过sslcontext将其传递给连接工厂。 (请注意,整个设置适用于ibmmq的docker实例)

我正在尝试使用的代码如下。

    /*
* (c) Copyright IBM Corporation 2018
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.ibm.mq.samples.jms;


import javax.jms.Destination;
import javax.jms.JMSConsumer;
import javax.jms.JMSContext;
import javax.jms.JMSException;
import javax.jms.JMSProducer;
import javax.jms.TextMessage;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509KeyManager;


import com.ibm.mq.jms.MQConnectionFactory;
import com.ibm.msg.client.jms.JmsConnectionFactory;
import com.ibm.msg.client.jms.JmsFactoryFactory;
import com.ibm.msg.client.wmq.WMQConstants;


import java.io.FileInputStream;
import java.io.Console;
import java.security.KeyStore;

/**
 * A minimal and simple application for Point-to-point messaging.
 *
 * Application makes use of fixed literals, any customisations will require
 * re-compilation of this source file. Application assumes that the named queue
 * is empty prior to a run.
 *
 * Notes:
 *
 * API type: JMS API (v2.0, simplified domain)
 *
 * Messaging domain: Point-to-point
 *
 * Provider type: IBM MQ
 *
 * Connection mode: Client connection
 *
 * JNDI in use: No
 *
 */
public class JmsPutGet {

    // System exit status value (assume unset value to be 1)
    private static int status = 1;

    // Create variables for the connection to MQ
    private static final String HOST = removed; // Host name or IP address
    private static final int PORT = 31201; // Listener port for your queue manager
    private static final String CHANNEL = "CLOUD.APP.SVRCONN"; // Channel name
    private static final String QMGR = removed; // Queue manager name
    private static final String APP_USER = "app"; // User name that application uses to connect to MQ
    private static final String APP_PASSWORD = removed; // Password that the application uses to connect to MQ
    private static final String QUEUE_NAME = "DEV.QUEUE.1"; // Queue that the application uses to put and get messages to and from


    /**
     * Main method
     *
     * @param args
     */
    public static void main(String[] args) {

        // Variables
        JMSContext context = null;
        Destination destination = null;
        JMSProducer producer = null;
        JMSConsumer consumer = null;

        try {

            // Load in the keystore for SSL certificates
            FileInputStream keyStoreInputStream = new FileInputStream("/other/dev/MQ/truststore.jks");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(keyStoreInputStream, ("changeit").toCharArray());
            keyStoreInputStream.close();

            // Create a keyManager that can select the certificate with the correct alias
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(keyStore, ("changeit").toCharArray());
            // final X509KeyManager defaultKm = (X509KeyManager)keyManagerFactory.getKeyManagers()[0];
            // X509KeyManager aliasKeyManager = new AliasKeyManagerWrapper(defaultKm, "server-certificate");

            // Create an SSLSocketFactory
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);

            // Get an SSLSocketFactory to pass to WMQ
            SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            MQConnectionFactory cf = new MQConnectionFactory();
            // set "client" connection mode for remote queue manager, as opposed to attempting to connect to a local queue manager
            cf.setTransportType(WMQConstants.WMQ_CM_CLIENT);

            cf.setSSLSocketFactory(sslSocketFactory);
             // System.setProperty("javax.net.ssl.trustStore", "truststore.jks");
            // System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
            // Set the properties
            cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, HOST);
            cf.setIntProperty(WMQConstants.WMQ_PORT, PORT);
            cf.setStringProperty(WMQConstants.WMQ_CHANNEL, CHANNEL);
            cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
            cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, QMGR);
            cf.setStringProperty(WMQConstants.WMQ_APPLICATIONNAME, "JmsPutGet (JMS)");
            cf.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, true);
            cf.setStringProperty(WMQConstants.USERID, APP_USER);
            cf.setStringProperty(WMQConstants.PASSWORD, APP_PASSWORD);
            cf.setStringProperty(WMQConstants.WMQ_SSL_CIPHER_SUITE, "TLS_RSA_WITH_AES_128_CBC_SHA256");

            // Create JMS objects
            context = cf.createContext();
            destination = context.createQueue("queue:///" + QUEUE_NAME);

            long uniqueNumber = System.currentTimeMillis() % 1000;
            TextMessage message = context.createTextMessage("Your lucky number today is " + uniqueNumber);

            producer = context.createProducer();
            producer.send(destination, message);
            System.out.println("Sent message:\n" + message);

            // consumer = context.createConsumer(destination); // autoclosable
            // String receivedMessage = consumer.receiveBody(String.class, 15000); // in ms or 15 seconds

            // System.out.println("\nReceived message:\n" + receivedMessage);

            recordSuccess();
        } catch (JMSException jmsex) {
            System.out.println(jmsex.toString());
            recordFailure(jmsex);
        } catch (Exception ex){
            System.out.println(ex.toString());
        }

        System.exit(status);

    } // end main()

    /**
     * Record this run as successful.
     */
    private static void recordSuccess() {
        System.out.println("SUCCESS");
        status = 0;
        return;
    }

    /**
     * Record this run as failure.
     *
     * @param ex
     */
    private static void recordFailure(Exception ex) {
        if (ex != null) {
            if (ex instanceof JMSException) {
                processJMSException((JMSException) ex);
            } else {
                System.out.println(ex);
            }
        }
        System.out.println("FAILURE");
        status = -1;
        return;
    }

    /**
     * Process a JMSException and any associated inner exceptions.
     *
     * @param jmsex
     */
    private static void processJMSException(JMSException jmsex) {
        System.out.println(jmsex);
        Throwable innerException = jmsex.getLinkedException();
        if (innerException != null) {
            System.out.println("Inner exception(s):");
        }
        while (innerException != null) {
            System.out.println(innerException);
            innerException = innerException.getCause();
        }
        return;
    }

}

我收到以下错误:

yatish.kadam@YKADAM-LT01:/other/dev/MQ$ java -Dcom.ibm.mq.cfg.useIBMCipherMappings=false -cp ./com.ibm.mq.allclient-9.1.4.0.jar:./javax.jms-api-2.0.1.jar:. com.ibm.mq.samples.jms.JmsPutGet
com.ibm.msg.client.jms.DetailedIllegalStateRuntimeException: JMSWMQ0018: Failed to connect to queue manager 'removed' with connection mode 'Client' and host name 'host name removed(31201)'.
Check the queue manager is started and if running in client mode, check there is a listener running. Please see the linked exception for more information.

我使用oracle java .. 1.8 ..ibmmq版本9 ...

我用来运行程序的命令...

java -Dcom.ibm.mq.cfg.useIBMCipherMappings=false -cp ./com.ibm.mq.allclient-9.1.4.0.jar:./javax.jms-api-2.0.1.jar:. com.ibm.mq.samples.jms.JmsPutGet

ibmmq上的错误

----- amqrmrsa.c : 961 --------------------------------------------------------
05/31/20 18:57:58 - Process(984.8768) User(mqm) Program(amqrmppa)
                    Host(qm-438f0c8bc007568-qmgr-0) Installation(Installation1)
                    VRMF(9.1.5.0) QMgr(VECNA.TEST.1)
                    Time(2020-05-31T18:57:58.942Z)
                    RemoteHost()
                    ArithInsert1(414)
                    CommentInsert1(????)
                    CommentInsert2(????)
                    CommentInsert3()

AMQ9633E: Bad SSL certificate for channel '????'.
EXPLANATION:
A certificate encountered during SSL handshaking is regarded as bad for one of
the following reasons: 
(a) it was formatted incorrectly and could not be validated 
(b) it was formatted correctly but failed validation against the Certification
  Authority (CA) root and other certificates held on the local system 
(c) it was found in a Certification Revocation List (CRL) on an LDAP server 
(d) a CRL was specified but the CRL could not be found on the LDAP server 
(e) an OCSP responder has indicated that it is revoked 
The channel is '????'; in some cases its name cannot be determined and so is
shown as '????'. The remote host is ''. The channel did not start. 
The details of the certificate which could not be validated are '????'. 
The certificate validation error was 0.
ACTION:
Check which of the possible causes applies on your system. Correct the error,
and restart the channel. 
This error might indicate that the remote end of the channel is configured to
send the wrong certificate. Check the certificate label configuration at the
remote end of the channel and ensure that the local key repository contains all
of the necessary CA certificates.
----- amqccisa.c : 8421 ---------------------------

密钥库内容:

Keystore type: jks
Keystore provider: SUN

Your keystore contains 3 entries

digicertrootca, May 31, 2020, trustedCertEntry, 
Certificate fingerprint (SHA1): 1F:B8:6B:11:68:EC:74:31:54:06:2E:8C:9C:C5:B1:71:A4:B7:CC:B4
digicertrootca11, May 31, 2020, trustedCertEntry, 
Certificate fingerprint (SHA1): 26:26:F7:42:08:95:39:27:8D:66:B6:51:49:12:D3:93:CA:2E:E1:9E
digicertrootca3, May 31, 2020, trustedCertEntry, 
Certificate fingerprint (SHA1): A8:98:5D:3A:65:E5:E5:C4:B2:D7:D6:6D:40:C6:DD:2F:B1:9C:54:36
java jms ibm-cloud ibm-mq truststore
1个回答
0
投票

@ joshmc谢谢..终于成功了。创建的客户端密钥必须使用特定的算法SHA256withRSA。

指向我找到的来源的链接。Digital certificates and CipherSpec compatibility in IBM MQ

使用以下命令创建新的自签名证书。

keytool -genkey -alias clientcert -keyalg RSA -sigalg SHA256withRSA -keysize 2048 -validity 3650 -keystore keystore.jks
© www.soinside.com 2019 - 2024. All rights reserved.