在客户机和队列管理器之间启用 TLS
本指南详细描述了如何在队列管理器与客户机应用程序之间启用标准 TLS 和相互 TLS 认证。 这将允许通过网络安全地发送和接收消息。
对于 MQ on Cloud V 9.2.1 修订版 2 及更高版本的队列管理器,缺省情况下将启用 TLS。 这些指示信息涵盖对该修订版下的队列管理器启用 TLS。
标准 TLS 可确保客户机信任与之通信的服务器。 相互 TLS 还涉及确保服务器信任客户机。 TLS 利用公用密钥密码术来加密网络上的消息。 属于可信服务器和应用程序的公用密钥存储在信任库中。 应用程序和服务器将自己的专用密钥存储在密钥库中。
先决条件
为了继续执行本教程,请务必确保您满足以下先决条件:
- IBM MQ on Cloud 队列管理器
- 如果您还没有 IBM MQ on Cloud 队列管理器,那么可以遵循 入门 来创建一个队列管理器。
- connection_info.txt 文件中下载的队列管理器的 连接详细信息
- 在 platformApiKey.json 文件中下载的管理员用户名和 API 密钥
- 在 apiKey.json 文件中下载的应用程序用户名和 API 密钥
- 如果您没有这些文件,那么可以查阅本教程末尾的附录 1,以了解如何获取这些文件。
- JMS 应用程序
- 本教程需要 JMS 应用程序才能成功完成。 建议您遵循附录 2 中详细描述的教程,以确保具有适用于本教程的 JMS 应用程序。
- IBM JDK
- 您需要 Java JDK 才能完成本教程。 建议您使用 IBM JDK。 此 JDK 包含对现代加密类型和更高级别安全性的支持,本教程需要这些支持。 您将利用
java
、javac
和ikeycmd
工具。 如果没有这些命令,请执行本教程末尾附录 3 中的步骤,以下载并安装 IBM JDK。 如果您正在 Mac OSX 上运行本教程,那么稍后将提供有关使用 keytool 而不是 ikeycmd 的指示信息。
- 您需要 Java JDK 才能完成本教程。 建议您使用 IBM JDK。 此 JDK 包含对现代加密类型和更高级别安全性的支持,本教程需要这些支持。 您将利用
- IBM MQ 客户机
- 要完成本教程,您需要 IBM MQ 命令行工具
runmqsc
安装并导出到您的PATH
中。 如果没有此命令,那么可以通过安装 IBM MQ 客户机来获取此命令。 本教程末尾的附录 4 详细说明了如何执行此操作。
- 要完成本教程,您需要 IBM MQ 命令行工具
使用标准(单向)TLS 保护应用程序
标准 TLS 认证可确保客户机只能与可信队列管理器进行对话,同时对在队列管理器与客户机之间传输的消息进行加密。
在文档的此部分中,您将首先演示客户机与队列管理器之间的现有非安全连接,然后将其转换为启用 TLS 的安全连接。
在队列管理器的通道上启用 TLS 后,需要将 JMS 应用程序配置为信任队列管理器,然后才能与其进行通信。 首先,导出队列管理器的安全证书的公共部分。 证书的此部分称为公用密钥。 MQ on Cloud 自带由 Let's Encrypt R3 提供的默认安全证书。 JMS 应用程序将在信任库中存储队列管理器公用密钥。 因此,将创建信任库,并向其中导入队列管理器公用密钥。 然后,JMS 应用程序将更新为使用该信任库。
步骤 1: 运行未加密的 JMS 应用程序
如果队列管理器是 V 9.2.1 修订版 2 或更高版本,那么您将无法在没有 TLS 的情况下运行 JMS,请移至 5 部分。
如果已完成先决条件,那么已经运行过 JMS 应用程序
必须运行 JMS 应用程序以确认它是否运行正常,但消息并未加密。 根据您的操作系统,使用以下命令:
- Windows
- 重新编译
javac -cp .\com.ibm.mq.allclient-9.0.4.0.jar;.\javax.jms-api-2.0.1.jar com\ibm\mq\samples\jms\JmsPutGet.java
- run
java -cp .\com.ibm.mq.allclient-9.0.4.0.jar;.\javax.jms-api-2.0.1.jar;. com.ibm.mq.samples.jms.JmsPutGet
- 重新编译
- Linux
- 重新编译
javac -cp ./com.ibm.mq.allclient-9.0.4.0.jar:./javax.jms-api-2.0.1.jar com/ibm/mq/samples/jms/JmsPutGet.java
- run
java -cp ./com.ibm.mq.allclient-9.0.4.0.jar:./javax.jms-api-2.0.1.jar:. com.ibm.mq.samples.jms.JmsPutGet
- 重新编译
下面是是预期的输出:
Your lucky number today is 283
SUCCESS
步骤 2: 通过 runmqsc 连接到队列管理器
必须在队列管理器上启用 TLS 通信。 您将使用命令 runmqsc
以连接到远程 MQ on Cloud 队列管理器。runmqsc
使用环境变量来确定要连接到的队列管理器的详细信息。
- 使用
export MQSERVER="CLOUD.ADMIN.SVRCONN/TCP/<HOSTNAME>(<PORT>)"
导出 MQ 变量,其中:<HOSTNAME>
- 这是文件 connection_info.txt 中的“主机名”<PORT>
- 这是文件 connection_info.txt 中的"listenerPort"
- 在控制台窗口中输入以下命令:
runmqsc -c -u <ADMIN_MQ_USER> -w60 <QUEUE_MANAGER_NAME>
其中:<ADMIN_MQ_USER>
- 这是 platformApiKey.json 文件中的"mqUsername<QUEUE_MANAGER_NAME>
- 这是文件 connection_info.txt 中的"queueManagerName"-c
通知runmqsc
它应使用 MQSERVER 变量连接到远程队列管理器
- runmqsc 将提示您输入密码 - 这是在引导式教程中下载的 PlatformApiKey.json 文件中的 API 密钥。
runmqsc
命令应显示身份验证成功。 终端将输出空行并等待用户输入。
步骤 3:为 TLS 配置队列管理器
连接到队列管理器后,可以配置单向 TLS 通信。
- 通过运行
DISPLAY CHANNEL(CLOUD.APP.SVRCONN)
来检查队列管理器的当前状态,这将显示将要更改的通道的当前设置。 - 通过运行
ALTER CHL('CLOUD.APP.SVRCONN') CHLTYPE(SVRCONN) SSLCIPH(ECDHE_RSA_AES_128_CBC_SHA256) SSLCAUTH(OPTIONAL)
更新通道以启用标准 TLS- 将
SSLCIPH
设置为ECDHE_RSA_AES_128_CBC_SHA256
和将SSLCAUTH
设置为OPTIONAL
将禁用相互验证,将 OPTIONAL 与密码规格设置相结合将启用标准 TLS。
- 将
- 运行
DISPLAY CHANNEL(CLOUD.APP.SVRCONN)
将确认更改已生效。 - 用
end
退出runmqsc
步骤 4: 重新运行 JMS 应用程序
现在重新运行 JMS 应用程序。 但这次 JMS 应用程序应该会失败,因为队列管理器强制实施了 TLS,但客户机应用程序尚未配置为使用 TLS。
- 在 Windows 上:
- run
java -cp .\com.ibm.mq.allclient-9.0.4.0.jar;.\javax.jms-api-2.0.1.jar;. com.ibm.mq.samples.jms.JmsPutGet
- run
- 在 Linux 上:
- run
java -cp ./com.ibm.mq.allclient-9.0.4.0.jar:./javax.jms-api-2.0.1.jar:. com.ibm.mq.samples.jms.JmsPutGet
- run
这是在最后一个 Java 回溯中显示的预期错误:
Caused by: com.ibm.mq.jmqi.jmqiException: CC=2;RC=2397;AMQ9641: Remote CipherSpec error for channel 'CLOUD.APP.SVRCONN' to host ''. [3=CLOUD.APP.SVRCONN]
步骤 5:导出队列管理器的公钥证书
JMS 应用程序需要信任队列管理器才能支持单向 TLS。 必须首先从服务器导出公用密钥,以便该密钥可以导入到应用程序信任库并由 JMS 应用程序使用。
- 单击要配置的队列管理器 - 这将显示有关此队列管理器的更多详细信息。
- 单击“密钥库”。 这就是存储队列管理器上安全证书的位置。
- 可以看到标注为“Default: qmgrcert”的缺省安全证书:
- 必须下载证书的公共部分。 单击证书右上角的三个点图标:
- 这将启动一个工具栏。 单击“下载公用证书”以下载证书的公用密钥。
具有 ARM 处理器的 M1 Mac 的其他步骤:
从 V 9.3.1 开始,此信息在如何使用 TLS 连接到队列管理器方面进行了更改时相关。
对于后台,MQ MacOS Toolkit 使用作为通用二进制文件提供的本机 MQ 客户机库来支持 x86 和 Arm64。 虽然工具箱本身由通用二进制文件组成,但它具有加密的下游依赖关系。 对于 x86,工具箱使用 GSKit,对于 Arm64,它使用 OpenSSL,这需要 TLS 的 .pem 格式的信任库。
这意味着当前存在导出以下环境变量的额外需求:
export MQSSLKEYR=<path_to_your_pem_file>/qmgrcert.pem
步骤 6: 创建信任库并导入队列管理器的公用密钥
以下命令将创建应用程序可用作信任库的密钥数据库。 导航至 JMS 应用程序所在的文件夹,然后执行以下命令:
仅在 Windows 和 Linux 环境中:
- 运行
ikeycmd -keydb -create -db <trustStoreName>.jks -pw <trustStorePassword> -type jks -expire 0
其中:<trustStorePassword>
- 选择一个密码,并记住它以备将来使用。
- 要将证书添加到新的信任库,请运行
ikeycmd -cert -add -db <trustStoreName>.jks -file qmgrcert.pem -label qmgrcert -pw <trustStorePassword>
在 Mac OSX 环境中,运行 keytool -importcert -file qmgrcert.pem -alias qmgrcert -keystore <trustStoreName>.jks -storepass <trustStorePassword>
现在,已成功创建密钥数据库以用作信任库,并且队列管理器的公用密钥已导入到新的信任库。
第 7 步:配置 JMS 应用程序以使用 TLS 信任存储
现在需要将 JMS 应用程序配置为使用新的信任库。
- 使用文本编辑器打开 JMS 应用程序,然后导航至以下代码部分:
try { // Create a connection factory JmsFactoryFactory ff = JMSFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER); JmsConnectionFactory cf = ff.createConnectionFactory();
- 紧接着以上显示的代码,插入以下内容:
cf.setStringProperty(WMQConstants.WMQ_SSL_CIPHER_SPEC,"ECDHE_RSA_AES_128_CBC_SHA256"); cf.setStringProperty(WMQConstants.WMQ_CHANNEL, "CLOUD.APP.SVRCONN"); cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT); System.setProperty("javax.net.ssl.trustStore", "<trustStoreName>.jks"); System.setProperty("javax.net.ssl.trustStorePassword", "<trustStorePassword>");
<trustStorePassword>
- 这与为保护密钥数据库而创建的密码相同。
步骤 8: 重新运行 JMS 应用程序
进行了这些更改后,请保存程序并对其进行重新编译,然后运行以下命令:
- Windows
- 重新编译
javac -cp .\com.ibm.mq.allclient-9.0.4.0.jar;.\javax.jms-api-2.0.1.jar com\ibm\mq\samples\jms\JmsPutGet.java
- run
java -cp .\com.ibm.mq.allclient-9.0.4.0.jar;.\javax.jms-api-2.0.1.jar;. com.ibm.mq.samples.jms.JmsPutGet
- 重新编译
- Linux
- 重新编译
javac -cp ./com.ibm.mq.allclient-9.0.4.0.jar:./javax.jms-api-2.0.1.jar com/ibm/mq/samples/jms/JmsPutGet.java
- run
java -cp ./com.ibm.mq.allclient-9.0.4.0.jar:./javax.jms-api-2.0.1.jar:. com.ibm.mq.samples.jms.JmsPutGet
- 重新编译
这次,程序应该能够成功地将消息“放入”队列管理器以及从队列管理器中“获取”消息。
现在,在网络上传输的消息已加密,并且客户机现在信任服务器。
使用相互(双向)TLS 保护应用程序
标准 TLS 通常在连接到服务器或 Web 站点时使用。 使用标准 TLS 时,客户机可以确信它连接到的是可信服务器。 相互 TLS 在此基础上,还确保服务器仅接受来自可信客户机的连接。 这同样是使用安全证书来实现的。
开始此部分之前,您应该已完成上面的“标准 TLS”部分。 JMS 客户机应用程序当前应该在使用标准 TLS 认证与队列管理器进行通信。 现在,您将启用相互 TLS。
步骤 1: 连接到队列管理器并对其进行配置
首先,需要配置队列管理器,并且必须强制实施相互认证。
- 运行
runmqsc -c -u <ADMIN_MQ_USER> -w60 <QUEUE_MANAGER_NAME>
以连接到队列管理器,其中:<ADMIN_MQ_USER>
- 这是 platformApiKey.json 文件中的"mqUsername<QUEUE_MANAGER_NAME>
- 这是文件 connection_info.txt 中的"queueManagerName"
- run
ALTER CHL('CLOUD.APP.SVRCONN') CHLTYPE(SVRCONN) SSLCIPH(ECDHE_RSA_AES_128_CBC_SHA256) SSLCAUTH(REQUIRED)
- 请注意,SSLCAUTH 已更改为“REQUIRED”。 这就是将队列管理器配置为只接受来自受信任客户端的通信。
步骤 2: 重新运行 JMS 应用程序
重新运行 JMS 应用程序。
- 在 Windows 上:
- run
java -cp .\com.ibm.mq.allclient-9.0.4.0.jar;.\javax.jms-api-2.0.1.jar;. com.ibm.mq.samples.jms.JmsPutGet
- run
- 在 Linux 上:
- run
java -cp ./com.ibm.mq.allclient-9.0.4.0.jar:./javax.jms-api-2.0.1.jar:. com.ibm.mq.samples.jms.JmsPutGet
- run
应用程序应该会失败,因为队列管理器已配置为使用相互 TLS,但客户机仍配置为使用标准 TLS。
第 3 步:创建密钥存储
现在必须创建密钥库,以用于存储专用证书供 JMS 应用程序使用。 导航至 JMS 应用程序所在的文件夹,然后执行以下命令:
仅在 Windows 和 Linux 环境中,运行 ikeycmd -keydb -create -db key -pw <keyStorePassword> -type jks -expire 0
并记下密码以供将来使用。
现在,已成功创建密钥数据库以用作密钥库。
通过运行 ls
可以确认文件系统中出现了一个名为 key.jks 的新文件。
步骤 4:为 JMS 应用程序创建自签名公钥/私钥对
- 创建自签名证书以供客户机使用:
- 在 Windows 和 Linux 环境中:
ikeycmd -cert -create -db key.jks -pw <keyStorePassword> -sig_alg SHA256WithRSA -label clientcert -dn "O=<Your Organisation>, C=<Your Country>"
<keyStorePassword>
- 为密钥存储文件选择一个密码<Your Organisation>
- 贵公司可能指定了特定的使用值,否则请使用自己的输入值<Your Country>
- 贵公司可能指定了特定的使用值,否则请使用自己的输入值
- 在 Mac OSX 环境中:
keytool -genkey -alias clientcert -keyalg RSA -sigalg SHA256withRSA -keysize 2048 -keystore key.jks -dname "O=<Your Organisation>, C=<Your Country>" -storepass mypass
- 在 Windows 和 Linux 环境中:
- 从密钥库中抽取安全证书的公用密钥:
- 在 Windows 和 Linux 环境中:
ikeycmd -cert -extract -db key.jks -pw <keyStorePassword> -label clientcert -target clientcert.pem
<keyStorePassword>
- 这是上面输入的密码,用于保护密钥存储空间。
- 在 Mac OSX 环境中:
keytool -export -keystore key.jks -storepass <keyStorePassword> -alias clientcert -file clientcert.cer
cat clientcert.cer | openssl x509 -inform DER >clientcert.pem
- 在 Windows 和 Linux 环境中:
第 5 步:配置 JMS 应用程序,为相互 TLS 使用密钥存储空间
- 使用首选文本编辑器打开 JMS 应用程序,然后导航至以下代码部分:
try { // Create a connection factory JmsFactoryFactory ff = JMSFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER); JmsConnectionFactory cf = ff.createConnectionFactory(); ...
- 紧接着以上显示的代码,插入以下代码:
System.setProperty("javax.net.ssl.keyStore", "key.jks"); System.setProperty("javax.net.ssl.keyStorePassword", "<keyStorePassword>");
<keyStorePassword>
- 这是为保护密钥存储空间而创建的密码。
第 6 步:将 JMS 公钥导入队列管理器信任存储区
为了使队列管理器信任客户机,下一步是将 JMS 客户机安全证书的公共部分导入到队列管理器的信任库;此操作可确保队列管理器信任客户机。 这可以通过 Web 用户界面来完成:
- 在可用列表中,单击队列管理器名称:
- 单击“信任库”选项卡,如下所示:
- 单击“导入证书”按钮:
- 在打开的窗口中,浏览以查找在先前步骤中抽取的公用证书。
- 为了使队列管理器刷新其安全性高速缓存并获取这些更改,请刷新队列管理器上的 SSL 安全性。
- 使用
runmqsc
命令连接队列管理器,执行REFRESH SECURITY TYPE(SSL)
命令 - 控制台将输出
AMQ8560I: IBM MQ security cache refreshed.
作为更改通知。 - 操作完成后,键入
end
断开 runmqsc 与队列管理器的连接
- 使用
运行刷新安全命令将结束与该队列管理器的所有连接,因此请考虑使用该命令的最佳时机
现在,队列管理器已配置为强制执行相互认证,并且客户机的公用密钥已添加到队列管理器的信任库。 因此,现在客户机应用程序和服务器将能够通过加密的通道进行通信。
步骤 7: 重新运行 JMS 应用程序
为了演示在客户机与服务器之间正确配置了相互 TLS,请重新编译程序并使用与平常一样的 Java 命令来运行程序:
- Windows
- 重新编译
javac -cp .\com.ibm.mq.allclient-9.0.4.0.jar;.\javax.jms-api-2.0.1.jar com\ibm\mq\samples\jms\JmsPutGet.java
- run
java -cp .\com.ibm.mq.allclient-9.0.4.0.jar;.\javax.jms-api-2.0.1.jar;. com.ibm.mq.samples.jms.JmsPutGet
- 重新编译
- Linux
- 重新编译
javac -cp ./com.ibm.mq.allclient-9.0.4.0.jar:./javax.jms-api-2.0.1.jar com/ibm/mq/samples/jms/JmsPutGet.java
- run
java -cp ./com.ibm.mq.allclient-9.0.4.0.jar:./javax.jms-api-2.0.1.jar:. com.ibm.mq.samples.jms.JmsPutGet
- 重新编译
本教程已成功完成。
附录
附录 1: 下载 IBM MQ on Cloud 文件
此部分描述了如何收集应该已在执行引导式教程期间下载,但之后可能丢失的各种文件。
Connection_info.json
要检索包含队列管理器连接详细信息的 connection_info.txt 文件,请执行以下操作:
- 单击表中显示的相关服务,登录 IBM Cloud 服务实例:
- 这将打开队列管理器视图:
- 选择要配置为使用 TLS 的队列管理器以打开下一个窗口。 选择“连接信息”按钮:
- 以“供人类使用的纯文本”格式下载此文件
PlatformApiKey.json
要创建或重置管理员 API 密钥,请执行以下操作:
- 点击表中显示的相关服务,登录 IBM Cloud 服务实例
服务实例
- 这将打开队列管理器视图。 选择要从中检索连接信息的队列管理器
- 接下来,选择 管理 选项卡
- 现在,单击重置 IBM Cloud API 密钥
- 注: 此 MQ 用户名的先前管理 API 密钥将 不再有效
- 注:如果该按钮显示创建 IBM Cloud API 密钥,说明您之前未以这种方式创建过 API 密钥。 请单击创建 IBM Cloud API 密钥按钮。
- 注: 此 MQ 用户名的先前管理 API 密钥将 不再有效
- 单击 下载 下载包含管理员用户名和密钥的 platformApiKey.json
apiKey.json
要创建新的应用程序 API 密钥,请执行以下操作:
- 点击表中显示的相关服务,登录 IBM Cloud 服务实例
服务实例
- 这将打开队列管理器视图。 选择 应用程序许可权 选项卡
- 现在,单击将用于 AMS 教程的应用程序旁边的 3 点
- 单击添加新的 API 密钥
- 注释。 现有应用程序 API 密钥将继续工作
- 注释。 现有应用程序 API 密钥将继续工作
- 单击 下载 以下载包含应用程序用户名和 API 密钥的 apiKey.json
附录 2:JMS 应用程序教程
使用以下链接中提供的教程来创建可连接到队列管理器并发送和接收简单消息的 JMS 应用程序。
要将 JMS 应用程序配置为连接到要用于此 TLS 教程的 MQ on Cloud 队列管理器,需要更改教程中的多个变量。 JMS 应用程序中需要更改的值如下:
所需的大部分值可在 connection_info.txt 文件中找到;该文件应已通过导游下载。 如果没有此文件,请查阅“附录 1”。 导游详细介绍了如何创建 "APP_USER "和 "APP_PASSWORD "变量,并将它们下载到名为 ‘apiKey.json' 的文件中,其中 "APP_PASSWORD "指的是 API 密钥。 如果没有此文件,请查阅“附录 1”。
- HOST = 在“connection_info.txt”文件中列示为“Hostname:”
- PORT = 在“connection_info.txt”文件中列示为“Listener port:”
- CHANNEL = 将此值更改为:“CLOUD.APP.SVRCONN”
- QMGR = 在“connection_info.txt”文件中列示为“Queue manager name:”
- APP_USER = 在“apiKey.json”文件中列示为“mqUsername:”
- APP_PASSWORD = 在“apiKey.json”文件中列示为“apiKey:”
- QUEUE_NAME = 不要更改此值
要创建基本的不安全 JMS 应用程序,请遵循 本教程
附录 3:下载并安装 IBM SDK**
- 下载 JDK
- 您应该从此处下载 IBM JDK。 选择适用于您平台的正确下载并进行安装。
- 根据下载的软件包,需要运行该软件包进行安装。
- 例如,如果您下载了 ibm-java-x86_64-sdk-8.0-5.17.bin,请运行
./ibm-java-x86_64-sdk-8.0-5.17.bin
- 对于 Windows,需要下载包含 JDK 的 Eclipse 软件包。
- 例如,如果您下载了 ibm-java-x86_64-sdk-8.0-5.17.bin,请运行
- 添加到 PATH
- 在 Windows 上
set PATH=C:\IBM_Eclipse\eclipseDevelopmentPackage\ibm_sdk80\bin;%PATH%
- 在 Linux 上
export PATH=<install location>/ibm-java-x86_64-80/jre/bin:<install location>/ibm-java-x86_64-80/bin:$PATH
- 在 Windows 上
附录 4:下载 IBM MQ 客户端
IBM 客户端需要使用 runmqsc
连接到队列管理器。
要获取有关各种可用 MQ 客户机版本的详细信息,请遵循 此链接。
选择最新软件包,编写时的最新版本为 9.3
-
您可以在 CD 选项卡下查看最新 CD 发行版的下载链接,在 LTS 选项卡下查看最新 LTS 维护发行版的下载链接,如下所示。
- CD 发行版
- LTS 发行版
- CD 发行版
-
单击 其他有用的链接,然后选择 IBM MQ 可重新分发的客户机。
-
如下图所示,勾选软件包左侧的方框,选择
IBM MQC redistributable client for <Your Operating System>
。 文件名中应该有 Redist。 本教程是使用 Linux Ubuntu 操作系统创建的 -
选择通过 HTTPS 下载,这将允许您直接通过浏览器下载客户端,如下图所示
。
- 注意:如果没有此选项,请尝试使用其他浏览器。
-
单击“继续”后, 会将您重定向到以下所示的屏幕。 单击下载图标以开始下载
-
下载完成后,将文件解压缩到您选择的目录
<PATH_TO_MQCLIENT_DIR>
中tar -xvzf <IBM-MQC-Redist>.tar.gz <PATH_TO_MQCLIENT_DIR>
-
向路径添加命令
export PATH=$PATH:<PATH_TO_MQCLIENT_DIR>/bin