我正在编写一个java客户端应用程序来连接TLS中配置的IBM-MQ队列管理器。
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();
}
}
但我得到的错误是:线程"main"中出现异常com.ibm.mq.MQException:MQJE001:完成代码"2",原因"2393"。
原因:java. io. IO异常:密钥库格式无效
bash-4.2$ mqrc 2393
2393 0x00000959 MQRC_SSL_INITIALIZATION_ERROR
所以想知道什么应该是正确的方式连接到它。作为. kdb文件,它被视为无效的密钥库格式。
下面是我用来在队列管理器端和java客户端应用程序端创建keystore.kdb的命令:
队列管理器MYSSL设置:-
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
为Java应用程序创建通用密钥库:
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
-----------
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$
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$
因此,我想知道什么是连接到队列管理器的正确方法,并从Java应用程序中配置TLS。
我还尝试了如下选项:
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");
它给我的错误如下:
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
甚至尝试了TLS_RSA_WITH_AES_256_CBC_SHA256
而不是TLS_RSA_WITH_AES_128_CBC_SHA256
,但没有运气
感谢@JoshMc的输入,我将. kdb转换为. jks格式,但我得到如下错误,作为参考,我粘贴了完整的控制台输出如下:
新代码:
//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");
控制台错误输出:
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)
为什么我得到返回代码2400提到不支持的密码套件:
$ mqrc 2400
2400 0x00000960 MQRC_UNSUPPORTED_CIPHER_SUITE
我用密码套件试过了:TLS_RSA_WITH_AES_128_CBC_SHA256
和TLS_RSA_WITH_AES_256_CBC_SHA256
两种。
如果我继续
System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "false")
然后给出不同的误差:
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)
注:在我看来,useIBMCipherMappings应该是默认值,即true,因此我将其保留为注解(从代码中删除):
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();
}
}
此外,我确保我的通道是正确配置与预期的密码套件:SSLCIPH(TLS_RSA_WITH_AES_256_CBC_SHA256)
通过命令:
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)
我还确保了密码是由我的JVM支持,通过以下链接:我的Java版本支持TLS_RSA_WITH_AES_256_CBC_SHA256。
TLS设置详细信息:
一个16b1x一个17b1x
此致,阿米特·M
1条答案
按热度按时间zzwlnbp81#
Java客户端不能使用kdb(CMS)密钥存储。您可以使用jks(Java密钥存储)或pkcs12(pfx或p12)密钥存储。
这个答案提供了一个从kdb创建jks的方法:
KDB到JKS密钥库转换