使用SSL从Java连接到MQ失败,出现错误MQJE001:完成代码“2”,原因“2397”

brc7rcf0  于 2023-09-29  发布在  Java
关注(0)|答案(2)|浏览(307)

Java程序使用SSL连接到MQ服务器并向MQ发送消息。上周还能用,现在不行了。以下是客户端的错误堆栈跟踪:

com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2397'.
        at com.ibm.mq.MQManagedConnectionJ11.<init>(MQManagedConnectionJ11.java:251)
        at com.ibm.mq.MQClientManagedConnectionFactoryJ11._createManagedConnection(MQClientManagedConnectionFactoryJ11.java:449)
        at com.ibm.mq.MQClientManagedConnectionFactoryJ11.createManagedConnection(MQClientManagedConnectionFactoryJ11.java:486)
        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:870)
        at com.ibm.mq.MQQueueManagerFactory.procure(MQQueueManagerFactory.java:818)
        at com.ibm.mq.MQQueueManagerFactory.constructQueueManager(MQQueueManagerFactory.java:760)
        at com.ibm.mq.MQQueueManagerFactory.createQueueManager(MQQueueManagerFactory.java:200)
        at com.ibm.mq.MQQueueManager.<init>(MQQueueManager.java:893)
        at MQUtility.main(MQUtility.java:405)
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2397;AMQ9204: Connection to host 'server.ip.address.number(1919)' rejected. [1=com.ibm.mq.jmqi.JmqiException[CC=2;RC=2397;AMQ9771: SSL handshake failed. [1=javax.net.ssl.SSLHandshakeException[Remote host terminated the handshake],3=MQServer_Name/server.ip.address.number:1919 (MQServer_Name),4=SSLSocket.startHandshake,5=default]],3=server.ip.address.number(1919),4=,5=RemoteTCPConnection.protocolConnect]
        at com.ibm.mq.jmqi.remote.api.RemoteFAP$Connector.jmqiConnect(RemoteFAP.java:13635)
        at com.ibm.mq.jmqi.remote.api.RemoteFAP$Connector.access$100(RemoteFAP.java:13175)
        at com.ibm.mq.jmqi.remote.api.RemoteFAP.jmqiConnect(RemoteFAP.java:1449)
        at com.ibm.mq.jmqi.remote.api.RemoteFAP.jmqiConnect(RemoteFAP.java:1390)
        at com.ibm.mq.ese.jmqi.InterceptedJmqiImpl.jmqiConnect(InterceptedJmqiImpl.java:377)
        at com.ibm.mq.ese.jmqi.ESEJMQI.jmqiConnect(ESEJMQI.java:562)
        at com.ibm.mq.MQSESSION.MQCONNX_j(MQSESSION.java:916)
        at com.ibm.mq.MQManagedConnectionJ11.<init>(MQManagedConnectionJ11.java:236)
        ... 10 more
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2397;AMQ9771: SSL handshake failed. [1=javax.net.ssl.SSLHandshakeException[Remote host terminated the handshake],3=MQServer_Name/server.ip.address.number:1919 (MQServer_Name),4=SSLSocket.startHandshake,5=default]
        at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.protocolConnect(RemoteTCPConnection.java:1493)
        at com.ibm.mq.jmqi.remote.impl.RemoteConnection.connect(RemoteConnection.java:1011)
        at com.ibm.mq.jmqi.remote.impl.RemoteConnectionSpecification.getNewConnection(RemoteConnectionSpecification.java:688)
        at com.ibm.mq.jmqi.remote.impl.RemoteConnectionSpecification.getSessionFromNewConnection(RemoteConnectionSpecification.java:282)
        at com.ibm.mq.jmqi.remote.impl.RemoteConnectionSpecification.getSession(RemoteConnectionSpecification.java:181)
        at com.ibm.mq.jmqi.remote.impl.RemoteConnectionPool.getSession(RemoteConnectionPool.java:127)
        at com.ibm.mq.jmqi.remote.api.RemoteFAP$Connector.jmqiConnect(RemoteFAP.java:13375)
        ... 17 more
Caused by: javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake
        at sun.security.ssl.SSLSocketImpl.handleEOF(Unknown Source)
        at sun.security.ssl.SSLSocketImpl.decode(Unknown Source)
        at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(Unknown Source)
        at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
        at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
        at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection$6.run(RemoteTCPConnection.java:1460)
        at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection$6.run(RemoteTCPConnection.java:1452)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.protocolConnect(RemoteTCPConnection.java:1452)
        ... 23 more
Caused by: java.io.EOFException: SSL peer shut down incorrectly
        at sun.security.ssl.SSLSocketInputRecord.read(Unknown Source)
        at sun.security.ssl.SSLSocketInputRecord.readHeader(Unknown Source)
        at sun.security.ssl.SSLSocketInputRecord.decode(Unknown Source)
        at sun.security.ssl.SSLTransport.decode(Unknown Source)
        ... 31 more

以下是从该路径C:\ProgramData\IBM\MQ\qmgrs\<mq-manager-name>\errors提取的错误日志:

----- amqrmrsa.c : 938 --------------------------------------------------------
9/22/2023 16:56:09 - Process(1532.229) User(SYSTEM) Program(amqrmppa.exe)
                      Host(MQSERVER_NAME) Installation(Installation1)
                      VRMF(9.0.3.0) QMgr(MQManager_Name)
                      Time(2023-09-22T21:56:09.933Z)
                     
AMQ9620: Internal error on call to SSL function on channel '????' to host
'client_host_name (server.ip.number)'.

EXPLANATION:
An error indicating a software problem was returned from a function which is
used to provide SSL or TLS support. The error code returned was '14'. The
function call was 'gsk_secure_soc_init'. 

The channel is '????'; in some cases its name cannot be determined and so is
shown as '????'. The channel did not start. 

The remote host name is 'client_host_name (server.ip.number)'.
ACTION:
Collect the items listed in the 'Problem determination' section of the System
Administration manual and use either the MQ Support site:
http://www.ibm.com/software/integration/wmq/support/, or IBM Support Assistant
(ISA): http://www.ibm.com/software/support/isa/, to see whether a solution is
already available.  If you are unable to find a match, contact your IBM support
center. 
----- amqccisa.c : 7846 -------------------------------------------------------
9/22/2023 16:56:09 - Process(1532.229) User(SYSTEM) Program(amqrmppa.exe)
                      Host(MQSERVER_NAME) Installation(Installation1)
                      VRMF(9.0.3.0) QMgr(MQManager_Name)
                      Time(2023-09-22T21:56:09.933Z)
                     
AMQ9999: Channel '????' to host 'client_host_name (server.ip.number)' ended abnormally.

EXPLANATION:
The channel program running under process ID 1532(1188) for channel '????'
ended abnormally. The host name is 'client_host_name (server.ip.number)'; in some cases
the host name cannot be determined and so is shown as '????'.
ACTION:
Look at previous error messages for the channel program in the error logs to
determine the cause of the failure. Note that this message can be excluded
completely or suppressed by tuning the "ExcludeMessage" or "SuppressMessage"
attributes under the "QMErrorLog" stanza in qm.ini. Further information can be
found in the System Administration Guide. 
----- amqrmrsa.c : 938 --------------------------------------------------------

请帮助我解决此错误。如果证书已过期,如何验证?我有一个在客户端使用的关键文件,它是由Java程序加载的。我不熟悉服务器上的MQ Server设置,但我有访问权限,如果您告诉我要检查什么,我可以给予一试。

q3qa4bjr

q3qa4bjr1#

如果上面日志中报告的版本是MQ 9.0.3 CD,则这 * 可能 * 是https://www.ibm.com/support/pages/apar/IT15806的潜在情况。应该注意的是,9.0.3已经很长时间不支持了,强烈建议您升级到当前的CD版本,或者如果CD发布周期太快,您的组织无法跟上,则迁移到当前的LTS版本。
要检查证书是否过期非常简单,只需将Java客户机应用程序中使用的JKS文件加载到IBM Key Management中,或者使用runmqckm / keytool访问密钥库。从那里,打印出证书详细信息并验证到期日期。
请注意,要执行上述操作,您需要JKS文件的密码,否则将无法访问它。
如果使用CLI,则需要的特定命令如下:runmqckm -cert -list -db [JKS file name] -pw [password]
这将打印出当前在密钥库中的所有证书。然后,您可以执行runmqckm -cert -details -db [JKS file] -pw [password] -label [cert_label],这将显示您想要的特定证书的详细信息。这些细节将包括发行日期和到期日期。

e3bfsja2

e3bfsja22#

除了@root提供的答案之外,我还想提供这个完整的指南来检查证书是否过期,创建一个新的证书,并将其部署到客户机和MQ服务器。
这里的场景是Java程序在客户机上运行,而MQ服务器安装在另一台Windows服务器上。
步骤:

  • 在客户机上启动并使用Java(JRE/JDK)keytool命令。打开命令行。
  • 确保相关的Java JDK/JRE版本位于环境PATH变量上
> SET PATH=%PATH%;C:\Program Files (x86)\java\jre1.8.0_xxx\bin
  • 检查证书是否过期,运行以下Java keytool命令行并检查输出:
> keytool -list -v -keystore path-to-file\keystore-file-name.jks
Enter keystore password: <keystore-password>

检查输出以确定证书是否过期。

  • 创建一个新的jks密钥文件:
>keytool -genkey -keyalg RSA -alias ibmwebspheremqmytestssl -keystore key-store-file-name.jks -storepass <key-store-password> -validity 400 -keysize 2048
What is your first and last name?
  [Unknown]:  MQ-server-name
What is the name of your organizational unit?
  [Unknown]:  Org Unit Name
What is the name of your organization?
  [Unknown]:  Org Name
What is the name of your City or Locality?
  [Unknown]:  City Name
What is the name of your State or Province?
  [Unknown]:  Province Name
What is the two-letter country code for this unit?
  [Unknown]:  Country
Is CN=xxx, OU=xxx, O=xxx, L=xxx, ST=xxx, C=xxx correct?
  [no]:  yes

Enter key password for <ibmwebspheremqmytestssl>
        (RETURN if same as keystore password): <press ENTER to accept the password specified above>

Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore mykeystore.jks -destkeystore keystore-file-name.jks -deststoretype pkcs12".
  • 验证新的密钥库文件:
> keytool -list -v -keystore path-to-file\keystore-file-name.jks
Enter keystore password: <key-store-password>
  • RDP到安装MQ的计算机
  • 启动CMD并转到放置有问题的MQ Manager的SSL证书存储库文件的文件夹:
C:>cd C:\ProgramData\IBM\MQ\qmgrs\mq-manager-name\ssl
C:\ProgramData\IBM\MQ\qmgrs\mq-manager-name\ssl>
  • 打开MQExplorer,并获取队列管理器的已配置密钥库。右键单击QueueManager,然后选择properties/SSL。检查SSL Key repositoryCertificate label
  • 备份并删除与为队列管理器配置的SSL相关的旧文件。例如,如果SSL Key repository的值为C:\ProgramData\IBM\MQ\qmgrs\mq-manager-name\ssl\mykeystore,则备份并删除以下文件:
mykeystore.jks
mykeystore.kdb
mykeystore.rdb
mykeystore.sth   (the password stash file)
  • 将上面创建的密钥库文件从客户机复制到MQServer上的上述文件夹。
  • 使用IBM MQ(通常在C:\Program Files\IBM\MQ\bin中)中的runmqckm.exe命令创建新的.kdb和.rdb文件:
C:\ProgramData\IBM\MQ\qmgrs\mq-manager-name\ssl> runmqckm -keydb -convert -db mykeystore.jks -new_format kdb
5724-H72 (C) Copyright IBM Corp. 1994, 2017.
A password is required to access the source key database.
Please enter a password: <keystore-password>
  • 创建新的stash .sth密码文件
C:\ProgramData\IBM\MQ\qmgrs\mq-manager-name\ssl> runmqckm -keydb -stashpw -db mykeystore.kdb
5724-H72 (C) Copyright IBM Corp. 1994, 2017.
A password is required to access the source key database.
Please enter a password: <keystore-password>
  • 在MQExplorer中,右键单击QueueManager,然后选择Properties/SSL。验证密钥库配置和标签名称。单击接受/确定。
  • 再次右键单击Queue Manager,然后选择Security/Refresh SSL。
  • 现在它应该已经准备好了,您可以从客户机测试Java程序,以使用SSL连接到MQ。
  • 如果遇到错误,请检查MQ服务器上以下文件夹中的日志,以查找有问题的队列管理器(例如C:\ProgramData\IBM\MQ\qmgrs\queue-manager-name\errors)。

相关问题