ssl 如何连接到在ibm-mq中启用TLS队列管理器

kg7wmglp  于 2023-03-08  发布在  其他
关注(0)|答案(1)|浏览(316)

我正在编写一个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_SHA256TLS_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

zzwlnbp8

zzwlnbp81#

Java客户端不能使用kdb(CMS)密钥存储。您可以使用jks(Java密钥存储)或pkcs12(pfx或p12)密钥存储。
这个答案提供了一个从kdb创建jks的方法:
KDB到JKS密钥库转换

相关问题