JMS to MQ message publishing error: "unable to find valid certification path to requested target"
JMS to MQ message publishing error: "unable to find valid certification path to requested target"
我正在尝试连接到支持 SSL 的 MQ 通道,以便使用 JMS(在 Spring 启动应用程序中)放置消息。下面是发送消息之前设置的连接工厂属性。我得到了
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
Djavax.net.ssl.trustStore
不是连接工厂 属性。您需要将其作为 Java 系统 属性 传递。 属性 的值必须是 JKS 或 PKCS12 文件。
您可以通过两种方式执行此操作:
- 作为
-D
命令行选项:
-Djavax.net.ssl.trustStore=D:\mq-message-handler-1.0\ssl\myCAcertfile.jks
- 使用
System.setProperty
:
System.setProperty(javax.net.ssl.trustStore, "D:\mq-message-handler-1.0\ssl\myCAcertfile.jks");
我正在尝试连接到支持 SSL 的 MQ 通道,以便使用 JMS(在 Spring 启动应用程序中)放置消息。下面是发送消息之前设置的连接工厂属性。我得到了 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
Djavax.net.ssl.trustStore
不是连接工厂 属性。您需要将其作为 Java 系统 属性 传递。 属性 的值必须是 JKS 或 PKCS12 文件。
您可以通过两种方式执行此操作:
- 作为
-D
命令行选项:-Djavax.net.ssl.trustStore=D:\mq-message-handler-1.0\ssl\myCAcertfile.jks
- 使用
System.setProperty
:System.setProperty(javax.net.ssl.trustStore, "D:\mq-message-handler-1.0\ssl\myCAcertfile.jks");