如何在启用TLS的情况下连接到IBM-MQ中的队列管理器。

huangapple go评论80阅读模式
英文:

how to connect to queue manager with TLS enabled in ibm-mq

问题

I understand that you have provided code and information about configuring an IBM-MQ queue manager with TLS and an associated Java client application. You are encountering errors related to keystore formats and cipher suites. Here are some recommendations:

  1. Keystore Format: It seems that you're having issues with keystore formats. Make sure you are using the correct keystore format for your Java client application. The code you provided specifies the keystore type as "JKS" (System.setProperty("javax.net.ssl.keyStoreType", "JKS")). Ensure that your keystore file is indeed in the JKS format.

  2. Cipher Suite: Verify that the cipher suite specified in your Java code ("TLS_RSA_WITH_AES_256_CBC_SHA256") matches the one configured in your MQ queue manager (SSLCIPH(TLS_RSA_WITH_AES_256_CBC_SHA256)). If they don't match, you may encounter compatibility issues.

  3. Use IBM Cipher Mappings: In your code, you've commented out the line that disables IBM Cipher Mappings (System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "false")). It's usually recommended to leave this property enabled (true) to use IBM's recommended cipher mappings. However, if you choose to disable it, make sure that your specified cipher suite is compatible with your IBM MQ installation.

  4. Certification Path: The error unable to find valid certification path to requested target typically indicates that your client is unable to validate the server's certificate. Ensure that the CA certificates required for certificate validation are present in the truststore (if configured).

  5. Key Repositories: Check the paths to your keystore and truststore files to ensure that they are accessible and contain the necessary certificates.

  6. Java Version: Confirm that your Java version supports the chosen cipher suite. It's good to verify this as different Java versions may have varying levels of support for encryption algorithms.

  7. Debugging: You can enable SSL debugging in your Java application by setting System.setProperty("javax.net.debug", "ssl"). This will provide more detailed information about the SSL handshake process and can help in diagnosing issues.

Make sure that you have followed your organization's security policies and best practices for handling certificates and keys. Additionally, consult the IBM MQ documentation and support resources for more specific troubleshooting information related to your version of IBM MQ and Java.

英文:

I am writing one java client application to connect to IBM-MQ queue manager configured in TLS.
Below is java code:

import com.ibm.mq.MQC;
import com.ibm.mq.MQEnvironment;
import com.ibm.mq.MQQueueManager;
//import com.ibm.mq.constants.CMQC;

public class IBMMQClient {
   public static void main(String[] args) throws Exception {
	    System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "false");
		System.setProperty("javax.net.ssl.keyStore", "C:\\ibm_mq\\temp\\genkey.kdb");

		System.setProperty("javax.net.ssl.keyStorePassword", "gen@123");

		MQEnvironment.hostname = "*************";//removed hostname for privacy
		MQEnvironment.port = 1419; // set the port number of the queue manager

		MQEnvironment.channel = "MYSSL.SVRCONN"; // set the channel name

		MQEnvironment.userID = "myuser";
		MQEnvironment.sslCipherSuite = "TLS_RSA_WITH_AES_128_CBC_SHA256"; // set the cipher suite to use for SSL/TLS


		MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY,MQC.TRANSPORT_MQSERIES_CLIENT);


		MQQueueManager qMgr = new MQQueueManager("MYSSL");
		System.out.println("Connected to " + qMgr.getName());
		qMgr.disconnect();
   }
}


But I am getting error as:
Exception in thread "main" com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2393'.

Caused by: java.io.IOException: Invalid keystore format

bash-4.2$ mqrc 2393

      2393  0x00000959  MQRC_SSL_INITIALIZATION_ERROR

So wanted to know what should be proper way to connect to it.
As .kdb file it is treating as invalid keystore format.

Below are the commands which I used to create keystore .kdb at queue manager side and java client application side:

queue manager MYSSL settings: -

cd /var/mqm/qmgrs/MYSSL/ssl

Creating key store:
---------------------------
runmqakm -keydb -create -db mysslkey.kdb -pw myssl@123 -type cms -stash

Creating self signed certficate
------------------------------
runmqakm -cert -create -label ibmwebspheremqmyssl -db mysslkey.kdb -dn "CN=myssl,OU=IBM" -expire 365 -size 1024 -format ascii

extracting a public certifcate
-------------------------------
runmqakm -cert -extract -label ibmwebspheremqmyssl -db mysslkey.kdb -target mysslpub.arm


Adding genpub.arm(public certficate from application keystore) in myssl key repos
-----------------------------------
runmqakm -cert -add -label genpub -file /var/mqm/qmgrs/MYSSL/ssl/temp/genpub.arm -db mysslkey.kdb 

To create generic keystore for java application:

cd /var/mqm/qmgrs/MYSSL/ssl/temp

Creating key store key database
-------------------------
runmqakm -keydb -create -db genkey.kdb -pw gen@123 -type cms -stash

creating selfsigned certificate:  
-------------------------------
runmqakm -cert -create -label ibmwebspheremqgen -db genkey.kdb -dn "CN=GEN,OU=IBM" -expire 365 -size 1024 -format ascii

extracting a public certificate
--------------------------------
runmqakm -cert -extract -label ibmwebspheremqgen -db genkey.kdb  -target genpub.arm


Adding public key(mysslkey.arm) of MYSSL queuemanage in genkey.kdb :
-----------------------------------
runmqakm -cert -add -label mysslpub -file /var/mqm/qmgrs/MYSSL/ssl/mysslpub.arm -db genkey.kdb -pw gen@123

-----------

final output of certificates inside mysslkey.kdb:

bash-4.2$ runmqakm -cert -list -db /var/mqm/qmgrs/MYSSL/ssl/mysslkey.kdb
Source database password :
Certificates found
* default, - personal, ! trusted, # secret key
!       genpub
-       ibmwebspheremqmyssl
bash-4.2$

final output of certificates inside genkey.kdb:

bash-4.2$ runmqakm -cert -list -db genkey.kdb
Source database password :
Certificates found
* default, - personal, ! trusted, # secret key
!       mysslpub
-       ibmwebspheremqgen
bash-4.2$

So wanted to know what should be proper way to connect to queue manager with TLS configured from java application.

Also I tried option as below:

 MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT);
       MQEnvironment.properties.put(MQC.SSL_CIPHER_SUITE_PROPERTY, "TLS_RSA_WITH_AES_128_CBC_SHA256");
       MQEnvironment.properties.put(MQC.MQCA_SSL_KEY_REPOSITORY, "C:\\ibm_mq\\temp\\genkey.kdb");

It gave me error as below:

Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
	at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
	at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297)
	at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:383)
	... 43 more

Even tried TLS_RSA_WITH_AES_256_CBC_SHA256 instead of TLS_RSA_WITH_AES_128_CBC_SHA256 but no luck

Thanks @JoshMc for input, I converted .kdb to .jks format, but I am getting error as below, for reference I pasted complete console output below:

New code:

 //commented useIBMCipherMappings to use default value of true
//System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "false");
	   
System.setProperty("javax.net.ssl.keyStore", "C:\\ibm_mq\\jks\\target.jks");
	  
	   System.setProperty("javax.net.ssl.keyStoreType", "JKS");

Console output of error:

Exception in thread "main" com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2400'.
	at com.ibm.mq.MQManagedConnectionJ11.constructMQCD(MQManagedConnectionJ11.java:1418)
	at com.ibm.mq.MQManagedConnectionJ11.constructCNO(MQManagedConnectionJ11.java:1511)
	at com.ibm.mq.MQManagedConnectionJ11.<init>(MQManagedConnectionJ11.java:237)
	at com.ibm.mq.MQClientManagedConnectionFactoryJ11._createManagedConnection(MQClientManagedConnectionFactoryJ11.java:450)
	at com.ibm.mq.MQClientManagedConnectionFactoryJ11.createManagedConnection(MQClientManagedConnectionFactoryJ11.java:487)
	at com.ibm.mq.StoredManagedConnection.<init>(StoredManagedConnection.java:97)
	at com.ibm.mq.MQSimpleConnectionManager.allocateConnection(MQSimpleConnectionManager.java:194)
	at com.ibm.mq.MQQueueManagerFactory.obtainBaseMQQueueManager(MQQueueManagerFactory.java:874)
	at com.ibm.mq.MQQueueManagerFactory.procure(MQQueueManagerFactory.java:822)
	at com.ibm.mq.MQQueueManagerFactory.constructQueueManager(MQQueueManagerFactory.java:764)
	at com.ibm.mq.MQQueueManagerFactory.createQueueManager(MQQueueManagerFactory.java:200)
	at com.ibm.mq.MQQueueManager.<init>(MQQueueManager.java:871)
	at IBMMQClient.main(IBMMQClient.java:64)

Why I am getting return code 2400 mentioning unsupported cipher suite:

 $ mqrc 2400

      2400  0x00000960  MQRC_UNSUPPORTED_CIPHER_SUITE

I tried with cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256 and TLS_RSA_WITH_AES_256_CBC_SHA256 both .

If I keep

System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "false")

Then it gives different error:

javax.net.ssl|DEBUG|10|main|2023-03-06 12:32:03.317 IST|SSLCipher.java:466|jdk.tls.keyLimits:  entry = AES/GCM/NoPadding KeyUpdate 2^37. AES/GCM/NOPADDING:KEYUPDATE = 137438953472
javax.net.ssl|ERROR|10|main|2023-03-06 12:32:04.154 IST|TransportContext.java:363|Fatal (CERTIFICATE_UNKNOWN): PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target (
"throwable" : {
  sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
  	at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:388)

Note: In my opinion useIBMCipherMappings should be default i.e. true hence I kept it commented(removed from code):

import com.ibm.mq.*;
import com.ibm.mq.constants.*;
import com.ibm.mq.headers.*;
import com.ibm.msg.client.wmq.common.*;

public class IBMMQClient {
   public static void main(String[] args) throws Exception {
	   System.setProperty("javax.net.debug", "ssl");

	   System.setProperty("javax.net.ssl.keyStore", "C:\\ibm_mq\\jks\\target.jks");
	  
	   System.setProperty("javax.net.ssl.keyStoreType", "JKS");
		  		    
	   System.setProperty("javax.net.ssl.keyStorePassword", "gen@123");
	   
	   MQEnvironment.hostname = "********";//removed hostname for privacy
	   MQEnvironment.port = 1419; // set the port number of the queue manager

      MQEnvironment.channel = "MYSSL.SVRCONN"; // set the channel name


	  MQEnvironment.userID = "myuser";
	  
	  MQEnvironment.sslCipherSuite = "TLS_RSA_WITH_AES_256_CBC_SHA256";
      
      MQQueueManager qMgr = new MQQueueManager("MYSSL");
      System.out.println("Connected to " + qMgr.getName());
      qMgr.disconnect();
   }
}

Also I made sure my channel is properly configured with expected cipher suite :SSLCIPH(TLS_RSA_WITH_AES_256_CBC_SHA256)
By command :

ALTER CHL(MYSSL.SVRCONN) CHLTYPE(SVRCONN) SSLCIPH(TLS_RSA_WITH_AES_256_CBC_SHA256)

REFRESH SECURITY TYPE(SSL)

bash-4.2$ runmqsc MYSSL
5724-H72 (C) Copyright IBM Corp. 1994, 2020.
Starting MQSC for queue manager MYSSL.


dis CHL(MYSSL.SVRCONN)
     1 : dis CHL(MYSSL.SVRCONN)
AMQ8414I: Display Channel details.
   CHANNEL(MYSSL.SVRCONN)                  CHLTYPE(SVRCONN)
   ALTDATE(2023-03-03)                     ALTTIME(10.57.24)
   CERTLABL( )                             COMPHDR(NONE)
   COMPMSG(NONE)                           DESCR( )
   DISCINT(0)                              HBINT(300)
   KAINT(AUTO)                             MAXINST(999999999)
   MAXINSTC(999999999)                     MAXMSGL(4194304)
   MCAUSER( )                              MONCHL(QMGR)
   RCVDATA( )                              RCVEXIT( )
   SCYDATA( )                              SCYEXIT( )
   SENDDATA( )                             SENDEXIT( )
   SHARECNV(10)                            SSLCAUTH(REQUIRED)
   SSLCIPH(TLS_RSA_WITH_AES_256_CBC_SHA256)
   SSLPEER( )                              TRPTYPE(TCP)

Also I made sure the cipher is supported by my JVM , by following below link:
https://confluence.atlassian.com/stashkb/list-ciphers-used-by-jvm-679609085.html
And TLS_RSA_WITH_AES_256_CBC_SHA256 is supported by my java version .

TLS settings details:

bash-4.2$ cd /var/mqm/qmgrs/MYSSL/ssl/
bash-4.2$ ls -al
total 36
drwxrws---  2 mqm mqm  4096 Mar  3 06:35 .
drwxrwsr-x 25 mqm mqm  4096 Mar  3 05:09 ..
-rw-------  1 mqm mqm    88 Mar  3 06:27 mysslkey.crl
-rw-------  1 mqm mqm 10088 Mar  3 06:28 mysslkey.kdb
-rw-------  1 mqm mqm    88 Mar  3 06:27 mysslkey.rdb
-rw-------  1 mqm mqm   193 Mar  3 06:27 mysslkey.sth
-rw-------  1 mqm mqm   749 Mar  3 06:27 mysslpub.arm


runmqsc MYSSL
ALTER QMGR SSLKEYR('/var/mqm/qmgrs/MYSSL/ssl/mysslkey')

ALTER CHL(MYSSL.SVRCONN) CHLTYPE(SVRCONN) SSLCIPH(TLS_RSA_WITH_AES_256_CBC_SHA256)

runmqsc MYSSL

DIS QMGR
     3 : DIS QMGR
AMQ8408I: Display Queue Manager details.
   QMNAME(MYSSL)                           ACCTCONO(DISABLED)
   ACCTINT(1800)                           ACCTMQI(OFF)
   ACCTQ(OFF)                              ACTIVREC(MSG)
   ACTVCONO(DISABLED)                      ACTVTRC(OFF)
   ADVCAP(ENABLED)                         ALTDATE(2023-03-03)
   ALTTIME(04.45.30)                       AMQPCAP(YES)
   AUTHOREV(DISABLED)                      CCSID(1208)
   CERTLABL(ibmwebspheremqmyssl)           CERTVPOL(ANY)
   CHAD(DISABLED)                          CHADEV(DISABLED)
   CHADEXIT( )                             CHLEV(DISABLED)
   CHLAUTH(ENABLED)                        CLWLDATA( )
   CLWLEXIT( )                             CLWLLEN(100)
   CLWLMRUC(999999999)                     CLWLUSEQ(LOCAL)
   CMDEV(DISABLED)                         CMDLEVEL(920)
   COMMANDQ(SYSTEM.ADMIN.COMMAND.QUEUE)    CONFIGEV(DISABLED)
   CONNAUTH(SYSTEM.DEFAULT.AUTHINFO.IDPWOS)
   CRDATE(2023-03-03)                      CRTIME(04.24.33)
   CUSTOM( )                               DEADQ( )
   DEFCLXQ(SCTQ)                           DEFXMITQ( )
   DESCR( )                                DISTL(YES)
   IMGINTVL(60)                            IMGLOGLN(OFF)
   IMGRCOVO(YES)                           IMGRCOVQ(YES)
   IMGSCHED(MANUAL)                        INHIBTEV(DISABLED)
   IPADDRV(IPV4)                           LOCALEV(DISABLED)
   LOGGEREV(DISABLED)                      MARKINT(5000)
   MAXHANDS(256)                           MAXMSGL(4194304)
   MAXPROPL(NOLIMIT)                       MAXPRTY(9)
   MAXUMSGS(10000)                         MONACLS(QMGR)
   MONCHL(OFF)                             MONQ(OFF)
   PARENT( )                               PERFMEV(DISABLED)
   PLATFORM(UNIX)                          PSMODE(ENABLED)
   PSCLUS(ENABLED)                         PSNPMSG(DISCARD)
   PSNPRES(NORMAL)                         PSRTYCNT(5)
   PSSYNCPT(IFPER)                         QMID(MYSSL_2023-03-03_04.24.33)
   REMOTEEV(DISABLED)                      REPOS( )
   REPOSNL( )                              REVDNS(ENABLED)
   ROUTEREC(MSG)                           SCHINIT(QMGR)
   SCMDSERV(QMGR)                          SPLCAP(ENABLED)
   SSLCRLNL( )                             SSLCRYP( )
   SSLEV(DISABLED)                         SSLFIPS(NO)
   SSLKEYR(/var/mqm/qmgrs/MYSSL/ssl/mysslkey)
   SSLRKEYC(0)                             STATACLS(QMGR)
   STATCHL(OFF)                            STATINT(1800)
   STATMQI(OFF)                            STATQ(OFF)
   STRSTPEV(ENABLED)                       SUITEB(NONE)
   SYNCPT                                  TREELIFE(1800)
   TRIGINT(999999999)                      VERSION(09020000)
   XRCAP(YES)

dis CHL(MYSSL.SVRCONN) ALL
     4 : dis CHL(MYSSL.SVRCONN) ALL
AMQ8414I: Display Channel details.
   CHANNEL(MYSSL.SVRCONN)                  CHLTYPE(SVRCONN)
   ALTDATE(2023-03-03)                     ALTTIME(10.57.24)
   CERTLABL( )                             COMPHDR(NONE)
   COMPMSG(NONE)                           DESCR( )
   DISCINT(0)                              HBINT(300)
   KAINT(AUTO)                             MAXINST(999999999)
   MAXINSTC(999999999)                     MAXMSGL(4194304)
   MCAUSER( )                              MONCHL(QMGR)
   RCVDATA( )                              RCVEXIT( )
   SCYDATA( )                              SCYEXIT( )
   SENDDATA( )                             SENDEXIT( )
   SHARECNV(10)                            SSLCAUTH(REQUIRED)
   SSLCIPH(TLS_RSA_WITH_AES_256_CBC_SHA256)
   SSLPEER( )                              TRPTYPE(TCP)

Regards,
Amit M

答案1

得分: 2

Java客户端无法使用kdb(CMS)密钥存储。您可以使用jks(Java密钥存储)或pkcs12(pfx或p12)密钥存储。

这个答案提供了一种从kdb创建jks的方法:

https://stackoverflow.com/questions/55233923/kdb-to-jks-keystore-conversion#55311445

英文:

Java clients can not use a kdb (CMS) key store. You can use either a jks (Java Key store) or pkcs12 (pfx or p12) key store.

This answer provides a method to create a jks from a kdb:

https://stackoverflow.com/questions/55233923/kdb-to-jks-keystore-conversion#55311445

huangapple
  • 本文由 发表于 2023年3月4日 00:09:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75629409.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定