本文提出了 IBM? JSSE(Java? Secure Socket Extension,Java? 安全套接字扩展)的配置问题,探讨了密钥库和信任库,并且对于如何在 IBM WebSphere? Application Server 环境下处理这些重要的 JSSE 元素提出了的建议。
引言 Java 安全套接字扩展(Java Secure Socket Extension,JSSE)是将低级编程接口封装到安全套接字层(Secure Socket Layer,SSL)协议及其相应的标准传输层安全性(Transport Layer Security,TLS)协议中的 Java 标准。IBM JSSE 是 JSSE 框架的 Java 实现。它支持 SSL V2 和 V3 以及 TLS V1。将 JSSE 这样架构以便其能够提供两套接口:一套被称为服务提供方接口(Service Provider Interface,SPI),而另一套是应用程序编程接口(Application Programming Interface,API)。
那些提供特定实现的功能插件使用提供的程序接口(本质上,是接口中的插件)。通常,应用程序开发人员仅处理 API。他们可以编写可移植的代码,该代码仅依赖于标准的公共 API 中公布的方法。IBM JSSE 实现也包括 IBM JSSE 加密提供方。
重要的是,开发人员应该遵循最佳的编程实践来启用应用程序的可移植性。只要没有将提供应用程序的特定信息的用法嵌入或强制编码到应用程序中,JSSE API 就可以进行移植。IBM 没有声明与其它 JSSE 提供方的互操作性。IBM 开发实验室没有执行任何正式的测试。
分离 API 和 SPI 接口的目的在于保护来源于程序提供者的应用程序,以便达到可移植性。但每个程序提供者所提供的功能可能不必与其它提供的功能相匹配。IBM JSSE 包括了 IBM 的提供方,而其他供应商拥有自己的提供方。当使用 WebSphere Application Server 时,例如,我们重在 IBM 自己的提供方。因此,应用程序代码假设任何特殊的提供方都是不可移植的。一个公共实例是显式地装载了 com.sun.* 类的应用程序代码。由于 com.sun.* 不是 JSSE(或者对于那种情况是 J2SE)的一部分,所以这样的代码是不可移植的。当您开发您的代码时,应该尽量避免程序提供者所特有的依赖。我们此处的实例说明了这种方法。
简化 JSSE 编程很大程度上是由于高级别的抽象,它提供了关于标准套接字的编程接口。这使得在两个希望使用 TCP/IP 协议上的传输层安全性来进行消息传递的终端之间建立网络连接变得非常容易。由 JSSE 提供的安全性服务是由传输层消息完整性、可靠性(加密)、服务器验证、以及可选的客户端验证组成。
在本文中,我们提出了 IBM JSSE 的配置问题,探讨了密钥库和信任库,并且推荐了在 WebSphere Application Server 环境下处理这些重要的 JSSE 元素的方法。随后,我们给出了 JSSE 编程模型并且说明当访问 HTTPS 上的可用资源时它是多么简单。最后,我们说明了怎样在单一应用程序中同时使用多重密钥库/信任库。
SSL 是由 Netscape Communications Corporation 于 1994 年开发的,而 TLS V1.0 是由 Internet Engineering Task Force(IETF)定义的标准,它基于 SSL V3.0,并且在使用的加密算法上与其有些许的不同。例如,SSL 使用 Message Authentication Code(MAC)算法来生成完整性校验值,而 TLS 应用密钥的 Hashing for Message Authentication Code(HMAC)算法。
配置及安装 IBM JSSE:我需要做什么吗? WebSphere Application Server V5(以及后续的)和 WebSphere Studio V5 一起传输 ibmjsse.jar(支持 JSSE 1.0.3 版本)及其相关的 certpath.jar。因此,IBM JSSE 由运行在 WebSphere Application Server 环境下的应用程序自动地使用。重申,WebSphere Application Server 包括了 JSSE 并完全地未经优化的支持它。您的部分中无需进一步的安装;事实上,禁止替换其他来源的 JSSE 或 JCE 实现。(您不能忽略核心的运行函数。当然,您可以拥有额外的提供方,但不能替换那里已存在的提供方)。您必须确保 JSSE 及其支持的 JAR 文件,例如 certpath.jar,在开发过程中位于您的类路径上(在运行时它们常常位于类路径上)。certpath.jar 是一个包,包含证书路径结构及 JSSE 运行时需要的验证功能,以便建立证书信任路径。您无需对 certpath.jar API 编程来建立 SSL/TLS 通信通道,但 JSSE 将会使用它。
IBM JSSE 提供了 JSSE 功能用于您的 WebSphere Application Server 环境以及部署过的应用程序。这是静态地设置在 java.security 配置文件中的,该文件位于您的 WAS 安装路径下的 JDK 目录中。下面是 Windows? 系统的 java.security 文件中未经优化的缺省提供方的清单。注意,不同平台之间的提供方的名称是一样的;然而,排序可能是不同的。无论何种平台,您的用于 WebSphere Application Sever 的未经优化的 JSSE 提供方都是 IBMJSSEProvider。
#
# List of providers and their preference orders
#
security.provider.1=sun.security.provider.Sun
security.provider.2=com.ibm.crypto.provider.IBMJCE
security.provider.3=com.ibm.jsse.IBMJSSEProvider
security.provider.4=com.ibm.security.cert.IBMCertPath
security.provider.5=com.ibm.crypto.pkcs11.provider.IBMPKCS11
您无需更改其中的任一个。如果您很好奇,那么此处存在大量的提供方,大多数都与 JSSE 无关。与 JSSE 相关的提供方只是 IBMJSSEProvider、IBMJCE 以及 IBMCertPath。后两者由 IBMJSSEProvider 隐含地使用来进行证书处理及加密操作。
信任库和密钥库:它们是什么以及我为何关注它们? SSL 协议基于公钥密码,加密密钥成对地出现在公钥密码中,它们是在数学上是相关的,但无法由一个推知另一个。这对加密密钥由私有密钥和公有密钥(私有,公共)组成的。私有密钥一直处于其所属实体的保护之下。注意,所有者确实拥有这对加密密钥,但公共密钥,如同它的名称所示,可以为众所周知,或至少自由地分散到与公共/私有密钥对通信的实体中。公钥密码启用的安全性服务是基于这样的消息解密机制,即共有密钥只能通过相应的私有密钥才能解密,反之亦然。这样,如果使用实体的公钥加密消息,那么可以保证只有该实体能够解密此消息。这时会在脑海中立即出现一个问题,即怎样确保正在使用的公钥的确被绑定到合法实体上而没有绑定到其它实体上。在此 Public Key Infrastructures(PKI)开始起作用了(请见参考资料)。
图 1. 客户端和服务器信任库/密钥库间的关系
公有密钥分布于名为公钥证书(PKC)的容器中。这些是由某一签名者(通常是 Certificate Authority,但公钥可以是自签名的)数字化地签署的。数字签名标志原始的真实性的验证。要记住的一点是相信计算机安全一定能通过计算的方法验证。为了验证公钥证书是合法的,我需要检验发出该签名的签名者。相反,这个过程是基于签名者的公有密钥的。
在这里使用信任库。当将 JSSE 用于 SSL 通信时,需要在本地存储中维护一套信任的签名者的证书,由此得名信任库。例如,由 JSSE 运行时使用的客户端信任库为了验证试图连接到服务器的客户端确实使用合法的证书(由信任的签名者发出的)与服务器交互。因此,服务器证书的签名者必须持有保存在客户端信任库中的 PKC。图 1 阐明了客户端和服务器信任库/密钥库间的关系。
出于同样的机制,服务器必须本地保护它的私有密钥并且使其能够访问 JSSE 运行时。在此处使用密钥库。密钥库与信任库有相同的格式,它只包含了不同的密钥。实际上,专业术语“密钥库”通常表示“信任库或密钥库”。
总之,信任库包含了签名者的证书,该签名者在使用信任库的环境中得到信任。另一方面,密钥库维护了实体的私有密钥,及其相应的 PKC。例如,当服务器面向客户端进行自身验证时,它需要从其密钥库中检索它的私有密钥来与加入客户端的 SSL 握手。所以,应该确实地重视信任什么签名者;也就是说,使用信任库的哪些内容。IBM 提供的缺省信任库包括了一些公认的且广泛信任的 Certificate Authorites(CA)。在这里一种好的实践是周期性地浏览您的信任库并且作出您关于其内容可信性的判断——可能删除一些 CA。
现在我们已经知道信任库是什么以及密钥库是什么,让我们来了解一下使用 IBM JSSE 在 WebSphere Application Server 环境中是如何定义它们的。
如何指定密钥库和信任库 为了打开 JSSE 的连接,您必须在信任库和密钥库中拥有合适的证书以及私有密钥。您需要配置 JVM 来使用您的信任库或密钥库。然而,如果您仅执行服务器验证(就是说,客户端使服务器的证书生效,但不允许反向),那么您只需要信任库。
如果您在没有明确地指定信任库或密钥库的情况下创建 SSL 连接,那么 JSSE 运行时将会使用“缺省”库。对于 WebSphere Application Server 来说,意味着 cacerts 文件被用作缺省的信任库(位于 WAS 安装目录下的 java/jre/lib/security 中)。
如果您联系的站点使用由公认的 CA 发出的证书,那么 IBM 提供的缺省证书很可能已经包含了您需要的信息。您可以使用 IBM 提供的 iKeyman 工具(WebSphere Application Server 安装后自动可用)打开 cacerts 文件来确定 JDK 中包含什么证书。
如果您访问的站点没有使用由 CA 发出的证书,CA 被包含在 WebSphere Application Server 中,那么您需要获得它们的签名证书并且将其添加到信任库中。我们推荐您不要修改现有的 JDK 文件,而是使用 iKeyman 创建新的信任库。然后您需要配置 WebSphere Application Server 运行时来使用该信用库,。