本节将说明如何设置基于安全套接字层 (Secure Socket Layer, SSL) 标准的连接服务,此连接服务在客户端与代理之间发送加密的消息。Message Queue 支持以下基于 SSL 的连接服务:
ssladmin 服务可使用 TCP/IP 传输协议在 Message Queue 命令实用程序 (imqcmd) 与代理之间创建一个安全的加密连接。不支持管理控制台 (imqadmin) 加密连接。
httpsjms 服务可使用 HTTPS 隧道 Servlet 通过 HTTP 传输协议在客户端与代理之间传送安全加密的消息。
本节后面部分将介绍如何使用 ssljms、 ssladmin 和 cluster 连接服务通过 TCP/IP 建立安全连接。有关使用 httpsjms 服务通过 HTTP 建立安全连接的信息,请参见附录 C,HTTP/HTTPS 支持。
要使用通过 TCP/IP 建立的基于 SSL 的连接服务,需要使用密钥工具实用程序 (imqkeytool) 生成公钥/私钥对。此实用程序将公钥嵌入自签名证书,此证书将传递给请求连接到代理的任何客户端,客户端需要使用该证书建立加密连接。本节介绍如何使用这样的自签名证书来设置基于 SSL 的服务。
如果需要更严密的验证,您可以使用由证书颁发机构验证的签名证书。若要使用签名证书,则除了使用自签名证书需要的步骤外,还需要其他一些步骤:必须先执行本节中介绍的步骤,然后再执行使用签名证书中的其他步骤。
Message Queue 对带有自签名证书的 SSL 支持用于保护所传输数据的安全性,并假定客户端正在与已知且可信任的服务器进行通信。以下过程说明了设置基于 SSL 的连接服务以使用自签名证书所需的步骤。下面各节更详细地介绍了每个步骤。
生成自签名证书。
在代理中启用 ssljms、ssladmin 或 cluster 连接服务。
启动代理。
配置并运行客户端。
此步骤仅适用于 ssljms 连接服务,不适用于 ssladmin 或 cluster 。
运行密钥工具实用程序 (imqkeytool) 为代理生成自签名证书。(在 UNIX® 系统上,您可能需要以超级用户 (root) 身份运行该实用程序,才能获取创建密钥库的权限。)可以对 ssljms、ssladmin 或 cluster 连接服务使用相同的证书。
imqkeytool -broker
密钥工具实用程序会提示您输入密钥库密码:
Generating keystore for the broker ... Enter keystore password:
然后,实用程序将提示您输入标识此证书所属的代理的信息。您提供的信息将构成 X.500 标识名。表 7–5 显示了一些提示和为每个提示提供的值。值区分大小写,并且可以包含空格。
表 7–5 自签名证书所需的标识名信息
提示 |
X.500 属性 |
描述 |
示例 |
---|---|---|---|
您的姓名是什么? |
commonName (CN) |
运行代理的服务器的全限定名称 |
mqserver.sun.com |
您所在部门的名称是什么? |
organizationalUnit (OU) |
部门或分部的名称 |
purchasing |
您的工作单位的名称是什么? |
organizationName (ON) |
大型工作单位的名称,如公司或政府机构 |
My Company, Inc. |
您所在城市或地区的名称是什么? |
localityName (L) |
城市或地区的名称 |
San Francisco |
您所在州或省的名称是什么? |
stateName (ST) |
州或省的全称,不要使用缩写 |
California |
此单位的两字母国家/地区代码是什么? |
country (C) |
标准两字母国家/地区代码 |
US |
输入信息后,密钥工具实用程序将显示这些信息以便于您确认。例如:
Is CN=mqserver.sun.com, OU=purchasing, ON=My Company, Inc., L=San Francisco, ST=California, C=US correct?
要接受当前值并继续,请输入 yes;要重新输入值,请接受默认值或输入 no。确认后,实用程序将生成密钥对而暂停其他操作。
接下来,实用程序要求您输入密码以锁定密钥对(密钥密码)。按 Return 键响应此提示,以使用同一密码作为密钥密码和密钥库密码。
请记住您指定的密码。启动代理时必须提供此密码,代理才能打开密钥库。可以将密钥库密码存储到密码文件中(请参见密码文件)。
密钥工具实用程序生成一个自签名证书,并将其放入 Message Queue 的密钥库。密钥库所在的目录因操作系统而异,如附录 A, Message QueueTM 数据在特定平台上的位置 中所示。
以下是适用于基于 SSL 连接服务的 Message Queue 密钥库的可配置属性:
imq.keystore.file.dirpath:包含密钥库文件的目录的路径。有关默认值的信息,请参见附录 A, Message QueueTM 数据在特定平台上的位置。
有时候您可能需要重新生成密钥对才能解决某些问题:例如,如果您在启动代理时忘记了密钥库密码或基于 SSL 的服务初始化失败,并收到了异常:
java.security.UnrecoverableKeyException:Cannot recover key
(出现异常的原因可能是因为您提供的密钥密码与您生成自签名证书时的密钥库密码不同。)
删除代理的密钥库。有关密钥库的位置,请参见附录 A, Message QueueTM 数据在特定平台上的位置。
再次运行 imqkeytool 生成新密钥对,如上所述。
要在代理中启用基于 SSL 的连接服务,您需要将 ssljms(或 ssladmin)添加到 imq.service.activelist 属性。
打开代理的实例配置文件。
实例配置文件位于一个由代理实例名称 (instanceName) 标识的目录中,而该实例名称与此配置文件是相关联的(请参见附录 A, Message QueueTM 数据在特定平台上的位置):
.../instances/instanceName/props/config.properties
为 imq.service. activelist 属性添加一个条目(如果此条目尚不存在),并将需要的基于 SSL 的服务包括在列表中。
默认情况下,此属性包括 jms 和 admin 连接服务。添加基于 SSL 的服务或希望激活的服务(ssljms 和/或 ssladmin):
imq.service.activelist=jms,admin,ssljms,ssladmin
基于 SSL 的 cluster 连接服务是使用 imq.cluster.transport 属性启用的,而不是使用 imq.service. activelist 属性启用的;请参见连接代理。
保存并关闭实例配置文件。
启动代理并提供密钥库密码。您可以通过以下两种方式之一提供密码:
让代理启动时提示您输入密码:
imqbrokerd Please enter Keystore password:
将密码放在密码文件中,如密码文件中所述。然后设置属性 imq.passfile.enabled = true 后,执行以下操作之一:
将密码文件的位置传递给 imqbrokerd 命令:
imqbrokerd -passfile /passfileDirectory/passfileName
启动代理时不使用 -passfile 选项,但使用以下两个代理配置属性指定密码文件的位置:
imq.passfile.dirpath=/passfileDirectory imq.passfile.name=passfileName
启用带有 SSL 的代理或客户端时,您可能会注意到它在几秒钟内使用了大量的 CPU 资源。这是因为 Message Queue 使用 JSSE(Java Secure Socket Extension,Java 安全套接扩展)方法 java.security.SecureRandom 来生成随机数,此方法需要大量时间生成初始随机数初始化向量。生成初始化向量后,CPU 的使用率将降到正常水平。
配置客户端以使用基于 SSL 的连接服务的过程各有不同,具体情况取决于客户端是应用程序客户端(使用 ssljms 连接服务)还是 imqcmd 之类的 Message Queue 管理客户端(使用 ssladmin 连接服务。)
对于应用程序客户端,您必须确保客户端在其 CLASSPATH 变量中指定了 .jar 文件:
imq.jar
jms.jar
如果您使用的是 Java 2 Software Development Kit (J2SDK) 1.4 之前的版本,您还必须包括 Java 安全套接扩展 (Java Secure Socket Extension, JSSE) 和 Java 命名和目录接口 (Java Naming and Directory Interface, JNDI) .jar 文件:
jsse.jar
jnet.jar
jcert.jar
jndi.jar
(如果使用的是 J2SDK 1.4 或之后的版本,则不需要包括这些文件,因为这些版本有内置的 JSSE 和 JNDI 支持。)
正确指定了 CLASSPATH 文件之后,启动客户端并连接到代理的 ssljms 连接服务的方法之一是输入如下命令:
java -DimqConnectionType=TLS clientAppName
这将通知连接使用基于 SSL 的连接服务。
对于管理客户端,可以通过在调用 imqcmd 命令时包含 -secure 选项来建立一个安全的连接:例如,
imqcmd list svc -b hostName:portNumber -u adminName -secure
其中 adminName 是 Message Queue 用户系统信息库中的有效条目。该命令将提示您输入密码。(如果使用的是平面文件系统信息库,请参见更改默认的管理员密码)。
列出连接服务是验证 ssladmin 服务是否正在运行的一种方法,也可以验证是否能成功建立安全的管理连接,如以下输出所示:
Listing all the services on the broker specified by: Host Primary Port localhost 7676 Service Name Port Number Service State admin 33984 (dynamic) RUNNING httpjms - UNKNOWN httpsjms - UNKNOWN jms 33983 (dynamic) RUNNING ssladmin 35988 (dynamic) RUNNING ssljms dynamic UNKNOWN Successfully listed services. |
签名证书可以提供比自签名证书更严密的服务器验证。您只能在客户端与代理之间实现签名证书,而不能在群集中的多个代理之间实现签名证书。除了上面介绍的配置自签名证书的步骤外,使用签名证书还需要其他一些步骤(见下文)。以下各节更详细地介绍了这些步骤。
以下过程说明如何获取和安装签名证书。
使用 J2SE keytool 命令为上一节中生成的自签名证书生成一个证书签名请求 (Certificate Signing Request, CSR)。
有关 keytool 命令的信息,可以参考
http://java.sun.com/j2se/1.5.0/docs/tooldocs/solaris/keytool.html
下面是一个示例:
keytool -certreq -keyalg RSA -alias imq -file certreq.csr -keystore /etc/imq/keystore -storepass myStorePassword |
这将生成一个 CSR,它将证书封装到指定的文件中(本例中是文件 certreq.csr )。
使用 CSR 生成或请求签名证书。
您可以通过以下两种方法之一完成:
由众所周知的证书颁发机构 (Certificate Authority, CA) 签署证书,如 Thawte 或 Verisign。有关如何操作的详细信息,请参见 CA 的文档。
使用 SSL 签名软件包亲自对证书进行签名。
最终的签名证书是一个 ASCII 字符序列。如果从 CA 收到签名证书,它可能是电子邮件附件或消息文本。
将签名证书保存到文件中。
以下说明使用示例名 broker.cer 来表示代理证书。
检查 J2SE 是否默认支持您的证书颁发机构。
此命令列出系统密钥库中的根 CA:
keytool -v -list -keystore $JAVA_HOME/lib/security/cacerts
如果您的 CA 已列出,请跳过下一步。
如果 J2SE 不支持您的证书颁发机构,请将 CA 的根证书导入到 Message Queue 密钥库中。
下面是一个示例:
keytool -import -alias ca -file ca.cer -noprompt -trustcacerts -keystore /etc/imq/keystore -storepass myStorePassword
其中 ca.cer 是包含从 CA 获取的根证书的文件。
如果您使用的是 CA 测试证书,则可能需要导入测试 CA 根证书。您的 CA 应提供有关如何获取副本的说明。
将签名证书导入到密钥库中以替换原来的自签名证书。
下面是一个示例:
keytool -import -alias imq -file broker.cer -noprompt -trustcacerts -keystore /etc/imq/keystore -storepass myStorePassword
其中 broker.cer 是包含从 CA 收到的签名证书的文件。
Message Queue 密钥库现在包含一个用于 SSL 连接的签名证书。
现在,您必须将 Message Queue 客户端运行时环境配置为请求签名证书,并确保客户端信任对该证书进行签名的证书颁发机构。
将连接工厂的 imqSSLIsHostTrusted 属性设置为 false。
默认情况下,客户端用来建立代理连接的连接工厂对象的 imqSSLIsHostTrusted 属性被设置为 true,表示客户端运行时环境将接受提供给它的任何证书。您必须将此值更改为 false,这样客户端运行时环境将尝试验证所有提供给它的证书。 如果证书签署人不在客户端的信任库中,验证将会失败。
验证签名机构是否已在客户端的信任库中注册。
要测试客户端是否会接受由您的证书颁发机构签名的证书,请尝试建立 SSL 连接,如上文配置并运行基于 SSL 的客户端中所述。如果 CA 在客户端的信任库中,连接将会成功,您可以跳过下一步。如果连接由于证书验证错误而失败,请执行下一步。
在客户端的信任库中安装签名 CA 的根证书。
默认情况下,客户端搜索密钥库文件 cacerts 和 jssecacerts,因此,如果您在两个文件中的任何一个中安装了证书,则无需进行进一步的配置。以下示例将文件 testrootca.cer 中的 Verisign 证书颁发机构的测试根证书安装到默认系统证书文件 cacerts 中。该示例假定 J2SE 安装在 $JAVA_HOME/usr/j2se 目录中:
keytool -import -keystore /usr/j2se/jre/lib/security/cacerts -alias VerisignTestCA -file testrootca.cer -noprompt -trustcacerts -storepass myStorePassword
还可以(并建议)将根证书安装到可选系统证书文件 jssecacerts 中:
keytool -import -keystore /usr/j2se/jre/lib/security/jssecacerts -alias VerisignTestCA -file testrootca.cer -noprompt -trustcacerts -storepass myStorePassword
第三种可能是将根证书安装到其他密钥库文件中,并配置客户端以使用该文件作为其信任库。以下示例将根证书安装到文件 /home/smith/.keystore 中:
keytool -import -keystore /home/smith/.keystore -alias VerisignTestCA -file testrootca.cer -noprompt -trustcacerts -storepass myStorePassword
默认情况下,客户端不搜索此密钥库,因此您必须明确地向客户端提供其位置,将其用作信任库。您可以在客户端运行后,通过设置 Java 系统属性 javax.net.ssl.trustStore 执行此操作:
javax.net.ssl.trustStore=/home/smith/.keystore