【问题标题】:Connecting to MQ channel using Java client :CERTLABL error使用 Java 客户端连接到 MQ 通道:CERTLABL 错误
【发布时间】:2018-08-10 13:40:16
【问题描述】:

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

JMSCMQ0001:IBM MQ 调用失败,compcode '2' ('MQCC_FAILED') 原因 '2059' ('MQRC_Q_MGR_NOT_AVAILABLE')

在MQ端报错CSQX673E,原因是:

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

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

据我了解,CERTLABL 不是证书的一部分。

【问题讨论】:

  • 这是不可能的,IBM MQ Classes for Java 和 IBM MQ Classes for JMS 不支持 TLS 的 SNI 功能,该功能允许它们在 TLS 协商期间发送通道名称。您需要连接到使用队列管理器默认证书的队列管理器上的通道。
  • 谢谢。甚至 Java 8 或 Java 9 也不支持这一点。 MQ 8.0 版的 MQ 客户端类是用 Java 7 编写的吗?也相信 Java 8 支持 SNI。

标签: java ssl ssl-certificate ibm-mq


【解决方案1】:

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


IBM 文档 IBM MQ 8.0.0 知识中心页面IBM MQ>Security>Security overview>IBM MQ security mechanisms>Security protocols in IBM MQ>The SSL or TLS key repository>Digital certificate labels, understanding the requirements 如下:

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

同一页面也记录了这一点:

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

在所有其他情况下,队列管理器 CERLABL 参数确定 发送的证书。特别是,以下仅收到 队列的CERTLABL参数配置的证书 经理,无论频道特定的标签设置如何:

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

IBM 还在 IBM MQ 8.0.0 知识中心页面IBM MQ>Reference>Configuration reference>Channel attributes>Channel attributes in alphabetical order>Certificate label (CERTLABL) 中记录了类似信息:

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


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

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

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

IBM 在技术说明“IBM WebSphere MQ: How does MQ provide multiple certificates (CERTLABL) capability”中记录了通道名称在 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 平台上,通道名称在转换为 ASCII 之前 应用此映射。例如,通道名称“TO.QMGR1”映射 到“to2e-qmgr1.chl.mq.ibm.com”的 SNI 地址。

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

【讨论】:

  • 嗨 Josh,您能否提供一些证据来支持“IBM 尚未在 IBM MQ Classes for Java 或 IBM MQ Classes for JMS 中实现该功能”这一说法。这对我得出结论真的很有帮助
  • @djhi89 直接在我的声明上方是来自 IBM MQ 文档的引用,其中我用粗体表示了直接表示 Java™ 客户端的声明,JMS 客户端不支持接收特定于通道的所需协议扩展证书。
  • @djhi89 您还亲自观察了问题中描述的行为。
  • @JoshMc 我有同样的问题,我根本不明白这个答案。在 MQ 方面,我在密钥库中有两个私有证书,客户端在其信任库中有公共部分。使用 qm 上的 CERTLBL 一切都适用于两个证书。但是,当我在通道上使用 CERTLBL 属性覆盖 qm CERTLBL 时,没有客户端可以连接并出现错误 AMQ9673:通道“XXX”没有向远程对等方发送正确的证书。此错误没有任何意义,因为文档状态通道 CERTLBL 用于覆盖 qm CERTLBL 属性。可选身份验证、MQ 9.0.5.0、AIX
  • @Talijanac 的客户端是基于 Java 的吗?
猜你喜欢
  • 1970-01-01
  • 2012-07-03
  • 2013-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-08
  • 2011-03-04
  • 2011-02-09
相关资源
最近更新 更多