JMS 到 MQ 消息发布错误:“无法找到请求目标的有效证书路径”
我正在尝试连接到启用 SSL 的 MQ 通道,以便使用 JMS(在 Spring boot 应用程序内)放置消息。以下是发送消息之前设置的连接工厂属性。我得到了 当 jms 尝试放置消息时出现以下错误。
Caused by: com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2397' ('MQRC_JSSE_ERROR')....
.....
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:203)
Caused by: 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:439)
at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306)
at java.base/sun.security.validator.Validator.validate(Validator.java:264)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132)
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:638)
... 81 more
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:434)
** 证书已在 QM 级别安装。 jms 客户端似乎没有从指定位置选择根证书。 CA根证书(myCAcertfile.cer)(自签名)是使用IBM mq中的runmqckm工具生成的。
MQ 通道信息
CHANNEL(KAU.CONN) CHLTYPE(SVRCONN)
ALTDATE(2014-02-28) ALTTIME(17.28.55)
CERTLABL( ) COMPHDR(NONE)
COMPMSG(NONE)
DESCR(Server-connection to windows host)
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_128_CBC_SHA256)
SSLPEER( ) TRPTYPE(TCP)
JMS 连接工厂属性
// Create a connection factory
JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
JmsConnectionFactory cf = ff.createConnectionFactory();
// 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, "Manual message publihser");
cf.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, true);
cf.setStringProperty(WMQConstants.USERID, "");
cf.setStringProperty(WMQConstants.PASSWORD, "");
System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "false" );
cf.setStringProperty("Djavax.net.ssl.trustStore", "D:\\mq-message-handler-1.0\\ssl\\myCAcertfile.cer");
cf.setStringProperty(WMQConstants.WMQ_SSL_CIPHER_SUITE, "TLS_RSA_WITH_AES_128_CBC_SHA256");
用于创建 CA 证书的命令
runmqckm -keydb -create -db myCA.kdb -type cms -pw mycakeypassword -stash
runmqckm -cert -create -db myCA.kdb -type cms -label "myCAcertificate" -dn "CN=demmoCA,O=DemmoOrg,OU=DemmoDepartment,L=DemmoLocation,C=UK" -expire 1000 -size 1024
runmqckm -cert -extract -db myCA.kdb -type cms -label "myCAcertificate" -target myCAcertfile.cer -format ascii -stashed
,然后使用密钥工具使用上述证书为客户端创建密钥库
keytool -keystore kautstclient.jks -genkey -alias winclientcert -storepass clientpassword
keytool -import -keystore kautstclient.jks -file myCAcertfile.cer -alias theCARoot
30/02/2022 更新 >我现在已使用以下命令将证书添加到客户端。
generating client side's CA to self sign the client's certificate
================================================================
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
creating certificate request from the jks in order to signed by the above CA.
===========================================================================
keytool -certreq -v -alias winclientcert -file kauclient.csr -keypass clientpassword -storepass clientpassword -keystore kautstclient.jks
signing the certificate requst(csr file) using the generated CA key
==================================================
openssl x509 -req -in kauclient.csr -CA cert.pem -CAkey key.pem -CAcreateserial -out kauclientown.crt
Import the the signed and then provided certificate certificate into your keystore using the following command:
========================================================================================
keytool -import -v -alias kauclientowncert -file kauclientown.crt -keystore kautstclient.jks -keypass clientpassword -storepass clientpassword
adding the client's key signed root CA in to queue manager's key.db
=================================================================
runmqckm -cert -add -db myqmgr.kdb -file cert.pem -label kauclientsignercertificate
I'm trying to connect to a SSL enabled MQ channel in order to place a message using JMS(within Spring boot app) . below are the connection factory properties set before sending the message. I'm getting the
following error when jms trying to put the message.
Caused by: com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2397' ('MQRC_JSSE_ERROR')....
.....
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:203)
Caused by: 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:439)
at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306)
at java.base/sun.security.validator.Validator.validate(Validator.java:264)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132)
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:638)
... 81 more
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:434)
** certificates are already installed at QM level. it seems jms client is not picking the root certificate from the specified location. the CA root certificate(myCAcertfile.cer) (self signed) was generated using runmqckm tool in IBM mq.
MQ channel information
CHANNEL(KAU.CONN) CHLTYPE(SVRCONN)
ALTDATE(2014-02-28) ALTTIME(17.28.55)
CERTLABL( ) COMPHDR(NONE)
COMPMSG(NONE)
DESCR(Server-connection to windows host)
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_128_CBC_SHA256)
SSLPEER( ) TRPTYPE(TCP)
JMS connection factory properties
// Create a connection factory
JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
JmsConnectionFactory cf = ff.createConnectionFactory();
// 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, "Manual message publihser");
cf.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, true);
cf.setStringProperty(WMQConstants.USERID, "");
cf.setStringProperty(WMQConstants.PASSWORD, "");
System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "false" );
cf.setStringProperty("Djavax.net.ssl.trustStore", "D:\\mq-message-handler-1.0\\ssl\\myCAcertfile.cer");
cf.setStringProperty(WMQConstants.WMQ_SSL_CIPHER_SUITE, "TLS_RSA_WITH_AES_128_CBC_SHA256");
Commands used to create CA's certificate
runmqckm -keydb -create -db myCA.kdb -type cms -pw mycakeypassword -stash
runmqckm -cert -create -db myCA.kdb -type cms -label "myCAcertificate" -dn "CN=demmoCA,O=DemmoOrg,OU=DemmoDepartment,L=DemmoLocation,C=UK" -expire 1000 -size 1024
runmqckm -cert -extract -db myCA.kdb -type cms -label "myCAcertificate" -target myCAcertfile.cer -format ascii -stashed
then created the keystore for the client using above certificate using key tool
keytool -keystore kautstclient.jks -genkey -alias winclientcert -storepass clientpassword
keytool -import -keystore kautstclient.jks -file myCAcertfile.cer -alias theCARoot
30/02/2022 update > I have now added the certificates to the client side using below commands.
generating client side's CA to self sign the client's certificate
================================================================
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
creating certificate request from the jks in order to signed by the above CA.
===========================================================================
keytool -certreq -v -alias winclientcert -file kauclient.csr -keypass clientpassword -storepass clientpassword -keystore kautstclient.jks
signing the certificate requst(csr file) using the generated CA key
==================================================
openssl x509 -req -in kauclient.csr -CA cert.pem -CAkey key.pem -CAcreateserial -out kauclientown.crt
Import the the signed and then provided certificate certificate into your keystore using the following command:
========================================================================================
keytool -import -v -alias kauclientowncert -file kauclientown.crt -keystore kautstclient.jks -keypass clientpassword -storepass clientpassword
adding the client's key signed root CA in to queue manager's key.db
=================================================================
runmqckm -cert -add -db myqmgr.kdb -file cert.pem -label kauclientsignercertificate
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Djavax.net.ssl.trustStore
不是连接工厂属性。您需要将其作为 Java 系统属性传递。该属性的值必须是 JKS 或 PKCS12 文件。您可以通过两种方式执行此操作:
-D
命令行选项:Djavax.net.ssl.trustStore
is not a connection factory property. You need to pass it as a Java system property. The value of the property needs to be either a JKS or PKCS12 file.You can do this in two ways:
-D
command line option:System.setProperty
: