英文:
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:
-
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. -
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. -
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. -
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). -
Key Repositories: Check the paths to your keystore and truststore files to ensure that they are accessible and contain the necessary certificates.
-
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.
-
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论