安全性对于使用 Web 服务交换业务数据至关重要。如果数据被第三方截取,或者欺骗性数据被当作有效数据接收,那么会引起严重的财务或法律后果。为 Web 服务(任何形式的数据交换)设计和实现应用程序的安全处理始终是可行的,但是这种方法比较冒险,因为即使是一个小错误和疏漏都会导致严重的安全漏洞。与其他更简单的数据交换相比,SOAP 的优势之一是它支持模块化扩展。自 SOAP 首次发布以来,安全性一直是扩展的主要关注点,促使了 WS-Security 和相关技术的标准化,允许针对每一个服务相应地配置安全性。
信息交换对安全性的需求通常包含三个方面:
机密性:只有消息的目标接收者有权访问消息内容。
完整性:接收到的消息没有发生任何修改。
真实性:可以对消息的来源进行检验。
WS-Security 可以让您轻松地满足这三个方面的要求。在本文中,您将理解如何通过使用 Axis2 和 Rampart WS-Security 扩展实现这点。但是,我们首先将扼要概述一下公开密匙加密的原理 — 这是 WS-Security 的加密和签名特性的主要基础。
公开密匙加密
纵观历史,安全消息交换一直以来都基于某种形式的共享秘密。这个秘密可能采用代码的形式,交换的双方使用经过商定的内容替换词语或操作。或者可以是密码的形式,通过某种算法将某种文本转换为其他文本。秘密甚至可以采用其他形式,比如对于可能访问消息的其他方未知的语言。共享秘密可以使消息交换非常安全。但是,如果其他方发现了这个秘密,那么消息交换就会泄漏,并会为消息交换方带来潜在的破坏性结果。(比如,想一想二战时期 Enigma 和 German 的军事通信)。
公开密匙加密是一种与其他加密有着本质区别的安全方法,它不需要共享的秘密。它所基于的理念是数学上的 “trap-door” 函数,它可以沿着一个方向轻松地进行计算,但是很难从相反的方向进行计算。比如,可以很容易找到两个质数的乘积(如果使用电脑的话,甚至可以是非常大的质数),但是很难通过分析乘积来找到原始的两个因数。如果围绕某个函数的简单方向构造一个加密算法,那么想要破解加密的任何人都需要从相反的方向来解密。和任何精心挑选的算法一样,破解加密的尝试将非常困难,以至于无法在可以对消息交换产生威胁的时间期限内完成(至少要等到有人开发了可用的量子计算机,或真正有效的特异功能)。
使用了公开密匙加密后,希望接收已加密消息的一方将创建一对密匙值。每个密匙值都可以单独用于加密消息,但是不能用于解密由它本身加密的消息。相反,这对密匙值的另外一个密匙必须用于解密。只要密匙的所有者将其中的一个密匙保密,另一个密匙就可以公开给他人。任何访问这个公开密匙的人都可以用它加密消息,而只有密匙所有者才能够对消息解密。由于使用了不同的密匙进行加密和解密消息,因此这种形式的加密被称为不对称加密。
消息签名
当使用您的公开密匙对消息进行加密,那么只有您(即私有密匙的持有者)才能够解密消息。这可以确保机密性,满足了安全消息交换三个方面的其中一个方面。但是也可以使用您的私有 密匙来加密消息,这样做之后,任何具有您的公开 密匙的人都可以解密这个消息。乍看上去这似乎没什么用 — 任何人都可以读取的加密消息有什么用?— 但是这种方法可以很好地充当一种检验真实性的机制。据称从您那里收到已加密消息的人可以使用您的公共密匙来解密消息并与预期值进行比较。如果值匹配的话,那么他们就知道是您 创建了这条消息。
在实际中,消息签名的过程不仅仅是使用私有密匙加密消息。首先,您需要使用某种方法为解密消息确立预期值。这通常使用另一种经过变化的数学 trap-door 函数完成:这是一个散列(hash)函数,它易于计算但难以复制(即很难在不修改该消息的散列值的情况下对消息进行修改,或者很难找到具有相同散列值的另一个消息作为提供的消息)。使用这种散列函数,可以为希望签名的消息生成散列值(在安全讨论中通常称为一个摘要(digest)),然后使用私有密匙加密该摘要并使用消息发送已加密的摘要值。任何接收此消息的人都可以对该消息使用相同的散列算法,然后使用您的公开密匙解密附带的已加密摘要,并比较两者的值。如果值匹配的话,那么接收方可以确定(在当前技术的范围内,并认为您一直对您的私有密匙保密)该消息是由您发送的。
在处理 XML 时,消息签名过程还涉及到另一个步骤。XML 消息以文本形式表示,但是文本表示的某些方面被 XML 认为是无关的(比如元素上的属性的顺序,或元素开始和结束标记内使用的空白)。由于这个与文本表示有关的问题,因此 W3C(XML 规范的所有者)决定在计算摘要值之前,将 XML 消息转换为一个标准的文本形式。一些标准化算法也得到定义,可以用于 XML 消息。只要消息交换的双方都同意使用相同的算法,那么具体使用哪种算法并不会产生什么影响。
使用经过签名的消息摘要可以同时保证消息完整性(因为对消息的修改将会改变摘要值)和真实性(因为您的私有密匙被用于加密摘要)。由于使用公开密匙的加密可以确保消息的私密性,因此消息交换安全性的所有主要方面都可以通过使用一个公开-私有密匙对涵盖。当然,对于一个密匙对,消息交换中只有一方是安全的 — 但是如果交换的另外一方也具有自己的公开/私有密匙对,那么就可以为消息交换的双方提供充分的安全性。