本文将描述新兴的 WS-Security 标准如何被用于保护 2002 年秋天开发和部署的 Web 服务。本文将讨论 Web 服务在安全性方面的需求,以及如何利用 HTTPS/SSL、数字证书和数字签名技术的组合来满足这些需求。本文将仔细讨论 S0AP 消息用来触发 Web 服务的 WS-Security 元素,并详细解释 WS-Security 元素的每一部分。
经过几年的时间,Web 服务已经从一种过分夸大的技术转变成了一种被许多组织投入使用且卓有成效的技术。早期的实现,与所有的新技术项目一样,往往是沙箱型(sandbox-type)项目或小型项目,在防火墙内并且本质上是非任务关键的(non-mission-critical)。那些试图投身于在因特网上传递 Web 服务这个领域的勇士们发现:他们必须要么提供开放的、任何人都可使用的服务(例如 XMethods 或 Amazon),要么开发自己的服务,这些服务通常是私有的,非常特定于某个公司并且采用某种安全模式。
早期把因特网作为传输工具的采用者通常使用某种形式的注册流程(例如 google)公开因特网服务,或者仅仅向一小部分与自己有着亲密、可信关系的业务伙伴提供服务。例如,为了使用 Google 的启用 Web 服务的搜索引擎,服务请求者必须首先用基于 HTML 的形式向 Google 注册。作为注册流程的一部分,Google 向请求者发送一封带有一个安全性“令牌”的邮件。当请求者调用服务时,他们向 Google 提供这个作为 SOAP 消息的一部分的令牌来证明他们是 Google Web 服务已注册的、已授权的用户。
在这些情况下,即使服务提供者使用的是 SOAP 之类的业界标准,还是需要提供有关安全性模式/流程的额外信息以使服务请求者能够使用服务。这样就会把请求者和提供者紧紧地捆绑在一起,而这种结果是双方都不喜欢的。
![]() ![]() |
![]()
|
显然,需要有一个保护 Web 服务的业界标准方法,2002 年 4 月,IBM、Microsoft 和 Verisign 对这种需求作出了反应。WS-Security 规范(另请参阅 参考资料)中描述到:
“WS-Security 描述通过消息完整性、消息机密性和单独消息认证提供保护质量的 SOAP 消息传递增强。这些机制可以用于提供多种安全模型和加密技术。
WS-Security 还提供一种将安全令牌和消息关联在一起的通用机制。WS-Security 不需要特定类型的安全令牌。它在设计时就被设计为可扩展的(例如支持多安全令牌格式)。例如,客户机可以提供身份证明以及他们有特定业务认证的证明。”
从 1997 年起,IBM 就有了一个名为“jStart(jump-start 的缩写)”的计划(请参阅 参考资料)用来帮助它的客户和业务伙伴使用新兴的技术。该计划的目标是帮助早期采用者利用新技术使他们的业务更加成功。去年秋天,“jStart 计划”与一家想用因特网作为传输工具来提供商家到商家 Web 服务的企业进行了合作。他们期望一种强级别的安全性和互操作性,于是他们决定使用 WS-Security 方法来保护与业务伙伴之间的 SOAP 消息流通。本文将讨论这个项目及该项目中对 WS-Security 的使用。
![]() ![]() |
![]()
|
随着客户应用程序用例的逐步发展,确定了一套有关安全性的非功能性需求:
- 客户与其业务伙伴之间的通信在因特网上传播时不应该被第三方看到。
- 客户必须能够确定消息来自哪个人并能够证实发送方就是那个发送方声称的发送方。
- 客户必须能够确定被传送的数据没有被篡改。
使用 HTTPS/SSL 传输安全性可以解决非功能性需求 #1。 因为这个应用程序将是个点到点应用程序,不涉及第三方服务提供者或者中介者,所以目前只是对使用密码术加密整个 SOAP 消息或加密 SOAP 消息的一部分这种想法进行了评价但还未实现。假如不涉及第三方,用来对 SOAP 消息的某一段进行加密的额外加密步骤所带来的价值就不足以证明实现某种形式的消息级加密所需的额外开发成本和复杂性是值得的。
使用数字签名和数字证书可以解决非功能性需求 #2 和 #3。当使用数字证书方法时,Web 服务请求者必须有一个由 可信认证中心签署的数字证书。请求者将使用这个证书来表明他们的身份,并对 SOAP 消息进行数字签名,这样就可以验证请求者的身份和消息的完整性。
一旦客户的系统接收到消息,就要对消息做时间戳记并进行日志记录。此时,数字签名会得到验证。验证过程将确保消息来自发送方,并且由于消息内容是在发送方的站点上签署的,所以还要验证消息内容在传输过程中没有被篡改。我们的客户在 DB2 中创建的 SOAP 消息日志将被用于实现不可抵赖性。
![]() ![]() |
![]()
|
既然您了解了需求和技术方法,让我们来看一下已经实现了什么。我们的客户选择作为 Web 服务来实现的应用程序是用 WebSphere Studio Application Developer 和一些来自 IBM alphaWorks Web 站点的工具(即 XML 安全套件(XML Security Suite))以及 Apache Axis 运行时(它是 IBM Web Services Toolkit 的一部分)开发的。虽然这个应用程序在驱动客户的核心业务应用程序时已经相当强大了,但因为它只实现了一个方法,所以还是比较简单。它被部署在 WebSphere Application Server 上并通过 WebSphere MQ Series 与客户的核心业务应用程序进行交互。
使用 Application Developer 的 TCP/IP 监视器,我们捕获了被发送到 Web 服务进行处理的 SOAP 消息。请注意,为了帮客户保密,我们对 SOAP URL 进行了一般化,除去了特定于应用程序的有效负载并稍微修改了一些计算结果:
|
让我们更详细地看一下 SOAP 消息。您可以清楚地看到,这是一个典型的 SOAP 消息,它最外层的一组起始与终止标记是 <soapenv:Envelope>
。SOAP 信封包含 <soapenv:Header>
部分与 <soapenv:Body>
部分。正如 WS-Security 规范定义的,WS-Security 部分被放置在 SOAP 头中,并且由 <wsse:Security>
起始与终止块(第 3-51 行)指定。 <Security>
Header 块提供了一种机制用来附加针对特定接收方(SOAP actor)的安全性方面的信息。因为在用例中只用到一个 SOAP actor,所以这个消息中只包含一个 <Security>
Header 块。
在第 3 行中,SOAP actor 属性定义了头条目的接收方, Security soapenv:actor="http://www.jStartcustomer.com/actors#verifier"
。第 3 行还包含 soapenv:mustUnderstand="1"
属性。我们通过将 SOAP mustUnderstand 属性设置为 "1"
来指出服务提供者必须处理 SOAP 头条目。按照 SOAP 规范,既然该属性被设置为 "1"
,如果接收方无法遵循语义(如元素的全限定名传达的那样),也无法根据这些语义处理消息的话,那么接收方就“必须”停止处理消息并生成一个错误。
第 4-14 行 <SignedInfo> </SignedInfo>
描述了已签署的消息内容。注意,数字签名应用程序习惯于使用一个 摘要来加快处理速度。这是一个标准的业界惯例,被用于提高性能。SOAP 消息的 payload(SOAP Body)很长,因此对整个消息采用公钥算法会大大影响 Web 服务的性能。为此使用了 摘要。摘要是长度固定的、短小的消息,可以快速生成和验证它的数字签名。当消息被接收时,Web 服务数字签名的验证程序(verifier)类(被实现为一个 Apache Axis 可插提供者)会计算这个摘要,并验证最新计算的摘要与对方发送的摘要是相匹配的。
我们来看一下那些构成消息已签署内容(Signed Content)部分的元素。第 5 行 <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
标识了规范(canonicalization)算法,这种算法被用来创建已签署信息的规范化格式(在本例中,即摘要)。由于 XML 文档以及处理它们的编程工具的特性,这个步骤是必需的。在有些情况下,XML 文档间会稍稍有些文字上的差别,但本质上还是同一份逻辑文档。序列化/反序列化 XML 数据结构时,注释的表示方法或 XML 解析器处理行分隔符的方法的细微变化都会使相同内容的二进制表示产生稍许的不同。如果验证数字签名的算法计算的是稍有不同的被序列化过的数据,那么结果将会是 fail,而实际上应该是 pass。
为了避免这个问题,首先得通过规范算法把文档转换为规范化格式。这个算法是 W3C Exclusive XML Canonicalization Version 1.0 规范(请参阅 参考资料)的一个实现,一个 W3C 推荐,它将文档转换为基本的规范化格式。这样我们就可以得到一致的二进制表示,这种一致的表示可以被正确比较,因此可以得出正确的结果。
第 6 行 <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
指出了签名方法算法(Signature Method Algorithm)。这个算法被用来将规范算法的输出转换成签名值(Signature Value)。我们的签名算法是依赖密钥的算法(RSA)和散列算法(SHA1)的结合。该算法是 W3C RFC 2437(请参阅 参考资料)中所描述的 RSASSA-PKCS1-v1_5 规范的一个实现。
第 7 行 <Reference URI="#sign_content_1043176028580">
指出了 Reference 元素。Reference 的可选 URI 属性标识了已签署的数据对象。Reference 块包含用来计算摘要的算法、计算后的摘要值以及计算摘要值之前需要执行的最后的转换。第 8-10 行 <Transforms> <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </Transforms>
指出了转换算法,而第 11 行和第 12 行指出了摘要算法和计算后的摘要值, <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <DigestValue>FLuQTa/LqDIZ5F2JSaMRHSRuaiQ=</DigestValue>
。
在我们的应用程序中,转换算法(Transform algorithm)也是上面讨论过的 W3C Exclusive XML Canonicalization 算法。用来计算摘要的方法,安全散列算法(Secure Hash Algorithm)是美国商业部/国家标准与技术研究院(U.S. Department of Commerce/National Institute of Standards and Technology)的安全散列标准的一部分。
第 15-16 行 <SignatureValue>kGlrrXjKku/WXKxID+JJkEXY+aGNYHc5dy8GwbLFtB5Msll2/MhwdnO9wastJ0gLPzLy3oHL
包含了一个签名值,实际上就是已加密的摘要值。这个值是第 6 行所指出的签名方法算法的输出。
7A8ggkMkjgAqnLg6PTzM7MdKoIAhe+xRHdOysamGucFJQRMrU+JQ4WATJt0bpdClwJy6mexT
Su48mq1q5rM9YZh61P7UEUKt+EQ=</SignatureValue>
第 20-48 行引入了密钥的概念。密钥被用来通过某种算法将一条普通的可读文本消息转换成一条不可读的、用来在因特网上传输的消息。我们的 Web 服务将用到公共/私有密钥(一对数学上相关的密钥)或者非对称密钥加密模式。其中的一个密钥是保密的;该密钥就是私有密钥。在我们的应用程序中,Web 服务请求者会在向服务提供者发送文档前用他的私有密钥签署摘要。
Key Value 块从第 20 行开始,该行标识了我们将使用的名称空间 — <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
。在 Key Value 块,即 <KeyValue> <RSAKeyValue> </RSAKeyValue> </KeyValue>
中,Web 服务请求者向 Web 服务提供者提供了所需的信息以便获得验证签名所需的密钥。在我们的消息中, KeyValue
元素包含了请求者的公共密钥,用来验证签名。我们选择了使用基于非对称 RSA(以三位发明者 Rivest、Shamir 和 Adleman 的名字命名)密钥的方法来满足不可抵赖性需求。
RSA 密钥模式的使用向 Web 服务提供者保证消息被接收到时格式仍然相同,并且是由提取出的数字证书的拥有者来签署的。如果重新计算后的摘要与 SOAP 消息中已加密的摘要相匹配的话,服务提供者就能够确认消息的完整性。通过在任何处理完成之前记录消息(该日志作为处理程序链中的第一个 Apache Axis 处理程序被实现),Web 服务提供者可以证明这个不确定的消息就是由签署消息的人发送的并且是被原封不动地接收的。
RSAKeyValue
元素有两段:
|
Exponent
|
RSA 模式使用了大质数来构建密钥对。Modulus 是两个大质数的乘积。每对密钥共享这个 Modulus,但是每对同时也有一个特定的指数。RSA 实验室有关当今加密术的常见问题解答,版本 4.1 文档(请参阅 参考资料)描述了怎样创建 Modulus 和 Exponent:
“取两个大质数 p 和 q,然后计算它们的乘积 n=pq;n 便是模数。选择一个数 e,比 n 小并且与 (p-1)(q-1) 互质,也就是说