Java Web 服务: Axis2 WS-Security 签名和加密

来源:developerWorks 中国 作者:Dennis Sosnoski
  
通过本文,您可以获得有关公开密匙加密基本原理的介绍,然后了解 WS-Security 如何通过结合公开-私有密匙对和秘密密匙,将这些原理应用于 SOAP 消息签名和加密。Dennis Sosnoski 将继续他的 Java Web 服务 系列,本期文章讨论 WS-Security 和 WS-SecurityPolicy 签名和加密特性,并提供了使用 Axis2 和 Rampart 的示例代码。

安全性对于使用 Web 服务交换业务数据至关重要。如果数据被第三方截取,或者欺骗性数据被当作有效数据接收,那么会引起严重的财务或法律后果。为 Web 服务(任何形式的数据交换)设计和实现应用程序的安全处理始终是可行的,但是这种方法比较冒险,因为即使是一个小错误和疏漏都会导致严重的安全漏洞。与其他更简单的数据交换相比,SOAP 的优势之一是它支持模块化扩展。自 SOAP 首次发布以来,安全性一直是扩展的主要关注点,促使了 WS-Security 和相关技术的标准化,允许针对每一个服务相应地配置安全性。

信息交换对安全性的需求通常包含三个方面:

  • 机密性:只有消息的目标接收者有权访问消息内容。
  • 完整性:接收到的消息没有发生任何修改。
  • 真实性:可以对消息的来源进行检验。

WS-Security 可以让您轻松地满足这三个方面的要求。在本文中,您将理解如何通过使用 Axis2 和 Rampart WS-Security 扩展实现这点。但是,我们首先将扼要概述一下公开密匙加密的原理 — 这是 WS-Security 的加密和签名特性的主要基础。

关于本系列

Web 服务构成了 Java™ 技术在企业计算应用中的关键部分。在 本系列文章 中,XML 和 Web 服务顾问 Dennis Sosnoski 介绍了对于使用 Web 服务的 Java 开发人员来说比较重要的主要框架和技术。通过跟随本系列的学习,您将了解到该领域的最新进展,并且知道如何使用它们来为您的编程项目提供帮助。

公开密匙加密

纵观历史,安全消息交换一直以来都基于某种形式的共享秘密。这个秘密可能采用代码的形式,交换的双方使用经过商定的内容替换词语或操作。或者可以是密码的形式,通过某种算法将某种文本转换为其他文本。秘密甚至可以采用其他形式,比如对于可能访问消息的其他方未知的语言。共享秘密可以使消息交换非常安全。但是,如果其他方发现了这个秘密,那么消息交换就会泄漏,并会为消息交换方带来潜在的破坏性结果。(比如,想一想二战时期 Enigma 和 German 的军事通信)。

公开密匙加密是一种与其他加密有着本质区别的安全方法,它不需要共享的秘密。它所基于的理念是数学上的 “trap-door” 函数,它可以沿着一个方向轻松地进行计算,但是很难从相反的方向进行计算。比如,可以很容易找到两个质数的乘积(如果使用电脑的话,甚至可以是非常大的质数),但是很难通过分析乘积来找到原始的两个因数。如果围绕某个函数的简单方向构造一个加密算法,那么想要破解加密的任何人都需要从相反的方向来解密。和任何精心挑选的算法一样,破解加密的尝试将非常困难,以至于无法在可以对消息交换产生威胁的时间期限内完成(至少要等到有人开发了可用的量子计算机,或真正有效的特异功能)。

使用了公开密匙加密后,希望接收已加密消息的一方将创建一对密匙值。每个密匙值都可以单独用于加密消息,但是不能用于解密由它本身加密的消息。相反,这对密匙值的另外一个密匙必须用于解密。只要密匙的所有者将其中的一个密匙保密,另一个密匙就可以公开给他人。任何访问这个公开密匙的人都可以用它加密消息,而只有密匙所有者才能够对消息解密。由于使用了不同的密匙进行加密和解密消息,因此这种形式的加密被称为不对称加密。

消息签名

当使用您的公开密匙对消息进行加密,那么只有您(即私有密匙的持有者)才能够解密消息。这可以确保机密性,满足了安全消息交换三个方面的其中一个方面。但是也可以使用您的私有 密匙来加密消息,这样做之后,任何具有您的公开 密匙的人都可以解密这个消息。乍看上去这似乎没什么用 — 任何人都可以读取的加密消息有什么用?— 但是这种方法可以很好地充当一种检验真实性的机制。据称从您那里收到已加密消息的人可以使用您的公共密匙来解密消息并与预期值进行比较。如果值匹配的话,那么他们就知道是您 创建了这条消息。

在实际中,消息签名的过程不仅仅是使用私有密匙加密消息。首先,您需要使用某种方法为解密消息确立预期值。这通常使用另一种经过变化的数学 trap-door 函数完成:这是一个散列(hash)函数,它易于计算但难以复制(即很难在不修改该消息的散列值的情况下对消息进行修改,或者很难找到具有相同散列值的另一个消息作为提供的消息)。使用这种散列函数,可以为希望签名的消息生成散列值(在安全讨论中通常称为一个摘要(digest)),然后使用私有密匙加密该摘要并使用消息发送已加密的摘要值。任何接收此消息的人都可以对该消息使用相同的散列算法,然后使用您的公开密匙解密附带的已加密摘要,并比较两者的值。如果值匹配的话,那么接收方可以确定(在当前技术的范围内,并认为您一直对您的私有密匙保密)该消息是由您发送的。

在处理 XML 时,消息签名过程还涉及到另一个步骤。XML 消息以文本形式表示,但是文本表示的某些方面被 XML 认为是无关的(比如元素上的属性的顺序,或元素开始和结束标记内使用的空白)。由于这个与文本表示有关的问题,因此 W3C(XML 规范的所有者)决定在计算摘要值之前,将 XML 消息转换为一个标准的文本形式(见 参考资料)。一些标准化算法也得到定义,可以用于 XML 消息。只要消息交换的双方都同意使用相同的算法,那么具体使用哪种算法并不会产生什么影响。

使用经过签名的消息摘要可以同时保证消息完整性(因为对消息的修改将会改变摘要值)和真实性(因为您的私有密匙被用于加密摘要)。由于使用公开密匙的加密可以确保消息的私密性,因此消息交换安全性的所有主要方面都可以通过使用一个公开-私有密匙对涵盖。当然,对于一个密匙对,消息交换中只有一方是安全的 — 但是如果交换的另外一方也具有自己的公开/私有密匙对,那么就可以为消息交换的双方提供充分的安全性。

证书

公开-私有密匙对可以同时用于对双方之间交换的信息进行加密和签名,假设交换双方都可以访问对方的公开密匙。这产生了一个问题,如何在保证安全性的情况下获得公开密匙。实现此目的的方法有许多种,其中最常用的是对公开密匙使用一个或多个可靠的第三方证明。数字证书 就是一种以第三方证明的形式提供公开密匙的机制。

数字证书实质上就是一个包装公开密匙的包装器,其中包含了用于密匙所有方的识别信息。然后由一个可信的第三方签名被封装的内容,并且签名被包括到证书中。可信的第三方通过使用其自己的签名发出证书,为公开密匙和识别信息做证明。当然,这又摆出了如何确立可信第三方的身份的自举问题。通常的解决方法是将某些称为发证机关(issuing authority)的可信第三方的证书硬编码到软件(比如 JVM)中。

除了这里描述的基本内容外,数字证书还涉及到很多其他内容,包括由于发生错误或泄漏私有密匙而需要撤回发出的证书,证书的有效期限,以及指定证书既定用途的扩展。参见 参考资料 获得有关数字证书和公开密匙加密的更多信息的链接。还可以查阅文档,获得 JDK 安装中附带的 keytool 安全工具。keytool 文档很好地介绍了证书结构和处理,以及 keystores(稍后讨论)和其他安全性内容。您还将在本文后面看到一个使用 keytool 的示例。

Keystores

大多数 Java 安全代码都使用 keystore 来处理私有密匙和数字证书。一个 keystore 实际上就是一个以加密形式包含密匙和证书条目的文件。需要使用密码才能访问 keystore。keystore 中的每个私有密匙会被再一次加密,需要额外的密码才能保持密匙的安全性。使用 keystore 和私有密匙的任何软件都需要在运行时保持 keystore 和私有密匙密码可用。这限制了由这些密码提供的安全性(因为任何访问源代码的人都可以了解到密码的载入方式)。因此您需要维护在其中托管了软件以及任何系统备份的系统的物理安全性。并且,要保护私有密匙的安全性,只能将 keystore 和密码放到该系统和系统备份中。

秘密密匙和对称加密

尽管使用非对称加密的公开密匙加密构成了许多有用 WS-Security 特性的基础,但是老式的秘密密匙加密仍然发挥着重要的作用。要实现相同程度的保护,非对称加密算法往往要比基于秘密密匙(同一个密匙同时用于加密和解密,意味着这个密匙必须始终保密)的对称算法涉及更多的计算量。由于这个原因,经常将这两种技术结合使用:高开销的非对称加密用于保障秘密密匙交换的安全性,秘密密匙然后又可用于低开销的对称加密。本文后面介绍 WS-Security 消息加密时,您将看到一个这样的示例。





设置

本文使用了与 “Axis2 WS-Security 基础” 相同的示例应用程序,该应用程序展现了如何使用 Axis2 和 Rampart 实现 WS-Security UsernameToken。但是,需要作出一些修改来支持使用 WS-Security 公开密匙加密特性,因此本文附带了一个单独的代码包(见 下载 )。

示例代码的根目录为 jws05code。该目录包含了以下内容:

  • 一个 Ant build.xml 文件
  • 一个 Ant build.properties 文件,它配置了示例应用程序的操作
  • library.wsdl 文件为示例应用程序提供了服务定义
  • log4j.properties 文件用于配置客户端登录
  • 一些属性定义 XML 文件(所有名为 XXX-policy-client.xml 或 XXX-policy-server.xml 的文件)

在开始使用示例代码前,需要完成以下操作:

  1. 编辑 build.properties 文件,设置 Axis2 安装的路径。

  2. 确保 Axis2 安装已经通过 Rampart 代码进行了更新,如 “Axis2 WS-Security 基础” 的 安装 Rampart 一节所述。(一种好方法就是查看 repository/modules 目录中的 rampart-x.y.mar 模块文件)。

  3. 将 org.bouncycastle.jce.provider.BouncyCastleProvider Bouncy Castle 安全提供者(用于示例代码中使用的公开密匙加密特性)添加到 JVM 安全配置中(lib/security/java.security 文件)(见 参考资料)。

  4. 将 Bouncy Castle JAR(名为 bcprov-jdkxx-vvv.jar,其中 xx 表示 Java 版本,vvv 表示 Bouncy Castle 代码版本)同时 添加到 Axis2 安装的 lib 目录和 Axis2 服务器应用程序的 WEB-INF/lib 目录。

现在,您已经准备好构建示例应用程序并尝试下一节将介绍的安全示例。


时间:2009-08-18 17:14 来源:developerWorks 中国 作者:Dennis Sosnoski 原文链接

好文,顶一下
(18)
81.8%
文章真差,踩一下
(4)
18.2%
------分隔线----------------------------


把开源带在你的身边-精美linux小纪念品
无觅相关文章插件,快速提升流量