JMS 到 MQ 消息发布错误:“无法找到请求目标的有效证书路径”

发布于 2025-01-17 04:39:43 字数 5878 浏览 1 评论 0原文

我正在尝试连接到启用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

七堇年 2025-01-24 04:39:43

Djavax.net.ssl.trustStore 不是连接工厂属性。您需要将其作为 Java 系统属性传递。该属性的值必须是 JKS 或 PKCS12 文件。

您可以通过两种方式执行此操作:

  1. 作为 -D 命令行选项:
    -Djavax.net.ssl.trustStore=D:\mq-message-handler-1.0\ssl\myCAcertfile.jks
    
  2. 使用System.setProperty:
    System.setProperty(javax.net.ssl.trustStore, "D:\mq-message-handler-1.0\ssl\myCAcertfile.jks");
    

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:

  1. As a -D command line option:
    -Djavax.net.ssl.trustStore=D:\mq-message-handler-1.0\ssl\myCAcertfile.jks
    
  2. Using System.setProperty:
    System.setProperty(javax.net.ssl.trustStore, "D:\mq-message-handler-1.0\ssl\myCAcertfile.jks");
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文