Transport level security with IBM WebSphere MQ in .net environment

Before we make this transport level security we have to make an queue manager with proper configuration. So first of all make sure to have following things in your queue manager.

  • IBM web sphere installation server’s user should be in mqm user group
  • Create an queue called XYZ

create a channel called ADMIN.TLS.SVRCONN with TLS_RSA_WITH_AES_128_CBC_SHA256

Create a SSL Required Channel

Create a SSL Required Channel

and here I set user as MUSER_MQADMIN , This user must be within “mqm” user group

mqm user group's user

mqm user group’s user

Set the web sphere mq server’s key data store location

key.kdb file location

WMQ server’s key.kdb file location

Create a CMS type key store in Web Sphere MQ server IBM websphere mq insalltion folder/QMgrs/QM_SSLConnect/SSL  (192.168.10.2)

IBM WMQ server's key store

IBM WMQ server’s key store

key store password

key store password

Create a self signed certificate for server

label name must be in lower letter case and start with ibmwebspheremq

IBM WMQ server's selfsigned certificate

IBM WMQ server’s selfsigned certificate

IBM WebSphere MQ SSL Connection (4)

extract this entry to certificate

Extract certificate

Extract certificate

Repeat this for Client side and create key store in SSL folder

Key store in client side

Key store in client side

here My user name is “herath” so label name must be ibmwebspherewebmqherath

Client certificate

Client certificate

if you want to get current user, you can use “whoami” command in cmd in your client machine

get current user from command prompt

get current user from command prompt

Then extract the certificate as clientcert.arm

Exchanging self-signed certificates 

Exchange self-signed certificates

Exchange self-signed certificates

now we need to import these certificates in to their respective key stores

Import client side self-signed ( clientcert.cert  )  certificate to server’s key-store

import client side certificate to server key store

import client side certificate to server key store

when it asks to enter label give ibmwebspheremqherath ( in your case your user name ibmwebspheremqxxx, xxx is your user name)

import client self-signed certificate

import client self-signed certificate

 

Repeat the same thing for server’s self-signed certificate in client side

import server's self-signed certificate

import server’s self-signed certificate

server's self-signed certificate label

server’s self-signed certificate label

After you complete these things , Then click the “Refresh SSL”

Refresh SSL

Refresh SSL

here is the code for connecting to SSL enabled web sphere channel


using IBM.WMQ;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WebsphereMQ
{
            public class SSLConnectionTest
        {
            const String connectionType = IBM.WMQ.MQC.TRANSPORT_MQSERIES_CLIENT;
            const String qManager = "QM_SSLConnect";
            const String hostName = "192.168.10.2";
            const String channel = "ADMIN.TLS.SVRCONN";
            const String port = "1480";
            const String sslKeyRepository = @"C:\Program Files (x86)\IBM\WebSphere MQ\ssl\key";
            const String cipherSpec = "TLS_RSA_WITH_AES_128_CBC_SHA256";
            const String cipherSuite = "SSL_RSA_WITH_AES_128_CBC_SHA256";

            public Hashtable init()
            {
                Hashtable properties = new Hashtable();

                properties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT);
                properties.Add(MQC.HOST_NAME_PROPERTY, hostName);
                properties.Add(MQC.PORT_PROPERTY, port);
                properties.Add(MQC.CHANNEL_PROPERTY, channel);

                properties.Add(MQC.SSL_CERT_STORE_PROPERTY, sslKeyRepository);
                properties.Add(MQC.SSL_CIPHER_SUITE_PROPERTY, cipherSuite);
                properties.Add(MQC.SSL_CIPHER_SPEC_PROPERTY, cipherSpec);

                return properties;
            }

            public void TestSSLConnection()
            {
                try
                {
                    Hashtable connectionProperties = init();
                    MQQueueManager qMgr = new MQQueueManager(qManager, connectionProperties);
                    MQQueue queue1 = qMgr.AccessQueue("XYZ", MQC.MQOO_OUTPUT | MQC.MQOO_FAIL_IF_QUIESCING);
                    MQMessage msg = new MQMessage();
                    msg.WriteUTF("Test Message");
                    queue1.Put(msg);

                }
                catch (MQException ex)
                {
                    Console.WriteLine("WebSphere MQ error occurred: {0}", ex.ToString());
                }
                catch (System.Exception ex)
                {
                    Console.WriteLine("System error occurred: {0}", ex.ToString());
                }
            }

            public void TestSSLConnectionWithCCDT()
            {
                try
                {
                    Environment.SetEnvironmentVariable("MQCHLLIB", @"D:\MQCCDT\QM_SSLConnect\");
                    Environment.SetEnvironmentVariable("MQCHLTAB", "AMQCLCHL.TAB");

                    Hashtable props = new Hashtable();
                    props.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT);
                    props.Add(MQC.SSL_CERT_STORE_PROPERTY, sslKeyRepository);
                    MQQueueManager qMgr = new MQQueueManager("QM_SSLConnect", props);

                    MQQueue queue1 = qMgr.AccessQueue("XYZ", MQC.MQOO_OUTPUT | MQC.MQOO_FAIL_IF_QUIESCING);
                    MQMessage msg = new MQMessage();
                    msg.WriteUTF("Test Message");
                    queue1.Put(msg);
                }
                catch (MQException ex)
                {
                    Console.WriteLine("A WebSphere MQ error occurred: {0}", ex.ToString());
                }
                catch (System.Exception ex)
                {
                    Console.WriteLine("A System error occurred: {0}", ex.ToString());
                }
            }

        }
}

I included TestSSLConnectionWithCCDT() method to connect with CCDT file. If you want to connect with CCDT , first you need to set client channel and then get the CCDT file into client machine. (please see my previous post to connect with CCDT )

put message in to client through .net application with SSL enabled channel

put message in to client through .net application with SSL enabled channel

This entry was posted in IBM WebSphere MQ and tagged , , , . Bookmark the permalink.

2 Responses to Transport level security with IBM WebSphere MQ in .net environment

  1. T.Rob says:

    Excellent post! Everything stated would generally work, but it is worth noting a couple of things since the behavior changes across versions.

    The certificate label requirements only come into play when MQ needs to find a personal certificate. When it searches for trusted certs it *always* uses the cryptographic elements of the cert such as fingerprint and signer chain to identify and validate the correct item. That said, it doesn’t hurt anything to use ibmwebspheremqherath as the label when adding that public cert to the trust store.

    The requirement on the client side as to the label of the certificate differs by version and technology. Please see: http://www-01.ibm.com/support/docview.wss?rs=0&uid=swg21245474

    When debugging a new TLS channel, if you go straight to mutually authenticated channels, the errors can be on either side. I normally recommend starting with a personal cert on the QMgr side *only* at first using SSLCAUTH(OPTIONAL), get the channel working, then add the personal cert on the client side and switch to SSLCAUTH(REQUIRED). This can drastically cut down on debugging time when setting up TLS for the first time on a QMgr. Please see https://t-rob.net/2015/03/12/managing-ca-signed-certificates/ for more on this implementation methodology.

Leave a comment