使用Java客户端连接到MQ通道:CERTLABL错误



我正在用Java开发一个微服务,通过SSL连接到IBM Websphere MQ V8.0。然而,我在日志中看到了这个错误:

JMSCMQ0001:IBM MQ调用失败,编译代码为"2"("MQCC_failed"),原因为"2059"("MQ RC_Q_MGR_NOT_AVAILABLE")

MQ端的错误为CSQX673E,原因是:

SSL或TLS通道的通道名称配置为使用证书标签:cert标签。但是,远程对等方没有发送必要的信息以允许本地通道使用正确的证书。远程主机已连接。

有人能告诉我如何使用Java传递这个参数吗。

据我所知,CERTLABL不是证书的一部分。


请注意,以下信息在MQ v8.0.0、v9.0.0和v9.1.0知识中心中的记录相同。


IBM文档IBM MQ 8.0.0知识中心页面IBM MQ>安全>安全概述>IBM MQ安全机制>IBM MQ中的安全协议>SSL或TLS密钥存储库>数字证书标签,了解以下要求:

IBM MQ Version 8.0支持在相同的队列管理器,使用每通道证书标签属性。到队列管理器的入站通道(例如,服务器连接或接收器)依赖于使用TLS服务器名称检测通道名称指示(SNI),以便从队列管理器。

同一页也记录了这一点:

请注意,入站信道(包括接收器、集群接收器、,不合格的服务器和服务器连接通道)仅发送如果远程对等端的IBM MQ版本完全支持证书标签配置,并且通道使用TLS密码规范。

在所有其他情况下,队列管理器CERTLABL参数确定发送的证书。尤其是以下内容由队列的CERTLABL参数配置的证书管理器,不考虑特定频道的标签设置:

  • 所有当前的Java和JMS客户端
  • 8.0版之前的IBM MQ版本

IBM还在IBM MQ 8.0.0知识中心页面IBM MQ>参考>配置参考>通道属性>按字母顺序排列的通道属性>证书标签(CERTLABL):中记录了类似信息

入站通道(包括RCVR、CLUSRCVR、不合格SERVER和SVRCONN通道)将仅在远程对等机的IBM®MQ版本完全支持证书标签配置,并且通道使用TLS CipherSpec。如果是不是这样,队列管理器CERTLABL属性确定证书已发送。此限制是因为证书标签入站通道的选择机制取决于TLS协议不是在所有情况下都支持的扩展特别是Java™客户端、JMS客户端以及8.0版之前的所有IBM MQ版本不支持所需的协议扩展,并且只支持接收队列管理器CERTLABL配置的证书属性,而不考虑特定于频道的标签设置


正如您所说,Java 8确实支持SNI,但显然IBM尚未在IBM MQ Classes for Java或IBM MQ Classies for JMS中实现该功能。

我能想到的一个可能的解决方案是,您可以找出MQ调用哪个底层函数来创建TLS会话,并覆盖它,将SNI属性设置为MQ将在队列管理器上识别的值,代码如下:

SSLParameters params = sslSocket.getSSLParameters();
params.setServerNames(serverNames);
sslSocket.setSSLParameters(params);

IBM在Technote"IBM WebSphere MQ:MQ如何提供多个证书(CERTLABL)功能":中记录了在SNI中传递通道名称的格式

MQ使用的SNI地址基于被请求,后跟后缀".chl.mq.ibm.com".

MQ通道名称映射为有效的SNI名称,如下所示:

  • 大写字母A-Z折叠为小写
  • 数字0到9保持不变
  • 包括小写字母a-z在内的所有其他字符都被转换为其2位十六进制ASCII字符代码,后跟连字符
  • 小写字母a到z分别映射到"61-"到"7a-">
  • 百分比(%)映射到"25-">
  • 连字符(-)映射到"2d-">
  • 点(.)映射到"2e-">
  • 正斜杠(/)映射到"2f-">
  • 下划线(_)映射到"5f-">

在EBCDIC平台上,通道名称在应用此映射。例如,通道名称"TO.QMGR1"映射到SNI地址"to2-qmgr1.chl.mq.ibm.com"。

相比之下,小写的通道名称"to.qmgr1"映射到SNI地址:"74-6f-2e-71-6d-67-72-1.chl.mq.ibm.com".

最新更新