实现 WS-Security(两个WEB服务在因特网上通信时不应该被第三方看到)

来源:互联网 发布:linux编译android程序 编辑:程序博客网 时间:2024/05/17 01:50
本文将描述新兴的 WS-Security 标准如何被用于保护 2002 年秋天开发和部署的 Web 服务。本文将讨论 Web 服务在安全性方面的需求,以及如何利用 HTTPS/SSL、数字证书和数字签名技术的组合来满足这些需求。本文将仔细讨论 S0AP 消息用来触发 Web 服务的 WS-Security 元素,并详细解释 WS-Security 元素的每一部分。

Web 服务安全 — 万事俱备

经过几年的时间,Web 服务已经从一种过分夸大的技术转变成了一种被许多组织投入使用且卓有成效的技术。早期的实现,与所有的新技术项目一样,往往是沙箱型(sandbox-type)项目或小型项目,在防火墙内并且本质上是非任务关键的(non-mission-critical)。那些试图投身于在因特网上传递 Web 服务这个领域的勇士们发现:他们必须要么提供开放的、任何人都可使用的服务(例如 XMethods 或 Amazon),要么开发自己的服务,这些服务通常是私有的,非常特定于某个公司并且采用某种安全模式。

早期把因特网作为传输工具的采用者通常使用某种形式的注册流程(例如 google)公开因特网服务,或者仅仅向一小部分与自己有着亲密、可信关系的业务伙伴提供服务。例如,为了使用 Google 的启用 Web 服务的搜索引擎,服务请求者必须首先用基于 HTML 的形式向 Google 注册。作为注册流程的一部分,Google 向请求者发送一封带有一个安全性“令牌”的邮件。当请求者调用服务时,他们向 Google 提供这个作为 SOAP 消息的一部分的令牌来证明他们是 Google Web 服务已注册的、已授权的用户。

在这些情况下,即使服务提供者使用的是 SOAP 之类的业界标准,还是需要提供有关安全性模式/流程的额外信息以使服务请求者能够使用服务。这样就会把请求者和提供者紧紧地捆绑在一起,而这种结果是双方都不喜欢的。





回页首

WS-Security 标准


显然,需要有一个保护 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 的使用。





回页首

为什么需要 WS-Security?

随着客户应用程序用例的逐步发展,确定了一套有关安全性的非功能性需求:

  1. 客户与其业务伙伴之间的通信在因特网上传播时不应该被第三方看到。
  2. 客户必须能够确定消息来自哪个人并能够证实发送方就是那个发送方声称的发送方。
  3. 客户必须能够确定被传送的数据没有被篡改。

使用 HTTPS/SSL 传输安全性可以解决非功能性需求 #1。 因为这个应用程序将是个点到点应用程序,不涉及第三方服务提供者或者中介者,所以目前只是对使用密码术加密整个 SOAP 消息或加密 SOAP 消息的一部分这种想法进行了评价但还未实现。假如不涉及第三方,用来对 SOAP 消息的某一段进行加密的额外加密步骤所带来的价值就不足以证明实现某种形式的消息级加密所需的额外开发成本和复杂性是值得的。

使用数字签名和数字证书可以解决非功能性需求 #2 和 #3。当使用数字证书方法时,Web 服务请求者必须有一个由 可信认证中心签署的数字证书。请求者将使用这个证书来表明他们的身份,并对 SOAP 消息进行数字签名,这样就可以验证请求者的身份和消息的完整性。

一旦客户的系统接收到消息,就要对消息做时间戳记并进行日志记录。此时,数字签名会得到验证。验证过程将确保消息来自发送方,并且由于消息内容是在发送方的站点上签署的,所以还要验证消息内容在传输过程中没有被篡改。我们的客户在 DB2 中创建的 SOAP 消息日志将被用于实现不可抵赖性。





回页首

Web 服务

既然您了解了需求和技术方法,让我们来看一下已经实现了什么。我们的客户选择作为 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 进行了一般化,除去了特定于应用程序的有效负载并稍微修改了一些计算结果:

        1.  <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"         xmlns:xsd="http://www.w3.org/2001/XMLSchema"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">        2.  <soapenv:Header>        3.  <wsse:Security soapenv:actor="http://www.jStartcustomer.com/actors#verifier"         soapenv:mustUnderstand="1"         xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext">        <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">        4.  <SignedInfo>        5.  <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>        6.  <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>        7.  <Reference URI="#sign_content_1043176028580">        8.  <Transforms>        9.  <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>        10.  </Transforms>        11.  <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>        12.  <DigestValue>FLuQTa/LqDIZ5F2JSaMRHSRuaiQ=</DigestValue>        13.  </Reference>        14.  </SignedInfo>        15.  <SignatureValue>        16.  kGlrrXjKku/WXKxID+JJkEXY+aGNYHc5dy8GwbLFtB5Msll2/MhwdnO9wastJ0gLPzLy3oHL        17.  7A8ggkMkjgAqnLg6PTzM7MdKoIAhe+xRHdOysamGucFJQRMrU+JQ4WATJt0bpdClwJy6mexT        18.  Su48mq1q5rM9YZh61P7UEUKt+EQ=        19.  </SignatureValue>        20.  <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">        21.  <KeyValue>        22.  <RSAKeyValue>        23.  <Modulus>        24.  2sW+eBjx5D2QMyr8ocZIZWNYHGf9zYhB4XWILPCTvhNV7dIe3l8ARepOA1ABFK2OMy        25.  pzb+Rb+nWQeo//yFz/28PmL63kdLiE72qmmQuzuPa5NXaV9pJ4JKw86QdLhGGpFIRH        26.  18Iugf3xLFwQEZqKYnblTUs7ftnTgW5r4HH492k=        27.  </Modulus>        28.  <Exponent>AQAB</Exponent>        29.  </RSAKeyValue>        30.  </KeyValue>        31.  <X509Data>        32.  <X509IssuerSerial>        33.  <X509IssuerName>OU=Java,O=IBM,L=Unknown,ST=Oklahoma,C=US</X509IssuerName>        34.  <X509SerialNumber>0</X509SerialNumber></X509IssuerSerial>        35.  <X509SubjectName>CN=John Doe</X509SubjectName>        36.  <X509Certificate>        37.  MIIB0TCCAToCAQAwDQYJKoZIhvcNAQEEBQAwTzELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE9rbGFo        38.  b21hMRAwDgYDVQQHEwdVbmsam3duMQwwCgYDVQQKEwNJQk0xDTALBgNVBAsTBEphdmEwHhcNMDIw        39.  OTI1MTAxMTQ4WhcNMDMwOTI1MTAxMTQ4WjATMREwDwYDVQQDEwhKb2huIERvZTCBnzANBgkqhkiG        40.  9w0BAQEFAAOBjQAwgYkCgYEA2sW+eBjx5D2QMyr8ocZIZWNYHGf9zYhB4XWILPCTvhNV7dIe3l8A        41.  RepOA1ABFK2OMypzb+Rb+nWQeo//yFz/28PmL63kdLiE72qmmQuzuPa5NXaV9pJ4JKw86QdLhGGp        42.  FIRH18Iugf3xLFwQEZqKYnblTUs7ftnTgW5r4HH492kCAwEAATANBgkqhkiG9w0BAQQFAAOBgQCs        43.  OD02WMoYcMR7Sqdb9oQyk7Nn4rQ5DBgZ5mxGGVzWxBZW/QON+Ir2j4KUjX1jalMvbHa9lnhPQmJi        44.  Ued923rza7fvdRG2CDalbW0R3aPd5q0u3akP0/Ejb7z5o88heajCSgfRruvU+ZdOTT3Oe+RBQgw8        45.  VuzbLApPnXiehowYuA==        46.  </X509Certificate>        47.  </X509Data>        48.  </KeyInfo>        49.  </Signature>         50.  </wsse:Security>        51.  </soapenv:Header>        52.  <soapenv:Body>        53.  application specific data/content        54.  </soapenv:Body>        55.  </soapenv:Envelope>:      

让我们更详细地看一下 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" ,如果接收方无法遵循语义(如元素的全限定名传达的那样),也无法根据这些语义处理消息的话,那么接收方就“必须”停止处理消息并生成一个错误。

SignedInfo 与摘要(digest)


第 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
7A8ggkMkjgAqnLg6PTzM7MdKoIAhe+xRHdOysamGucFJQRMrU+JQ4WATJt0bpdClwJy6mexT
Su48mq1q5rM9YZh61P7UEUKt+EQ=</SignatureValue>
包含了一个签名值,实际上就是已加密的摘要值。这个值是第 6 行所指出的签名方法算法的输出。

密钥


第 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 元素有两段:

Modulus
<Modulus>2sW+eBjx5D2QMyr8ocZIZWNYHGf9zYhB4XWILPCTvhNV7dIe3l8ARepOA1ABFK2OMypzb+Rb+nWQeo//yFz/28PmL63kdLiE72qmmQuzuPa5NXaV9pJ4JKw86QdLhGGpFIRH18Iugf3xLFwQEZqKYnblTUs7ftnTgW5r4HH492k=</Modulus>



Exponent
<Exponent>AQAB</Exponent>

RSA 模式使用了大质数来构建密钥对。Modulus 是两个大质数的乘积。每对密钥共享这个 Modulus,但是每对同时也有一个特定的指数。RSA 实验室有关当今加密术的常见问题解答,版本 4.1 文档(请参阅 参考资料)描述了怎样创建 Modulus 和 Exponent:

“取两个大质数 p 和 q,然后计算它们的乘积 n=pq;n 便是模数。选择一个数 e,比 n 小并且与 (p-1)(q-1) 互质,也就是说 e 和 (p-1)(q-1) 之间除了 1 外没有其他公因子。找出另一个数 d,即 (p-1)(q-1) 除以 (ed-1)。e 和 d 两个值分别被称为公共指数与私有指数。公共密钥是(n,e) 这一对;私有密钥是 (n,d)。”

服务请求者用他们的私有密钥对消息进行数字签名。在服务提供者一方,使用请求者的公共密钥验证签名。由于服务请求者是用私有的非对称密钥签署的消息,因此就向服务提供者保证了只有私有密钥的持有者才能签署消息。

数字证书


Key Info 块的下一部分就是数字证书本身,由 <X509Data> 元素指出。数字证书被用来识别消息的发送方,采用同样的方法可以利用用户标识来识别 Web 和企业应用程序的用户。这个数据块中的第一个元素确定签署证书的组织。这个组织通常是认证中心。在本例中,那些信息已经被普通的信息替换掉了: <X509IssuerSerial> <X509IssuerName>OU=Java,O=IBM,L=Unknown,ST=Oklahoma,C=US</X509IssuerName> <X509SerialNumber>0</X509SerialNumber></X509IssuerSerial>

下一个是 <X509SubjectName>CN=John Doe</X509SubjectName> 元素,它包含服务请求者(本案例中就是 John Doe)的专有名称以及 X.509 证书本身:

<X509Certificate>MIIB0TCCAToCAQAwDQYJKoZIhvcNAQEEBQAwTzELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE9rbGFob21hMRAwDgYDVQQHEwdVbmsam3duMQwwCgYDVQQKEwNJQk0xDTALBgNVBAsTBEphdmEwHhcNMDIwOTI1MTAxMTQ4WhcNMDMwOTI1MTAxMTQ4WjATMREwDwYDVQQDEwhKb2huIERvZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2sW+eBjx5D2QMyr8ocZIZWNYHGf9zYhB4XWILPCTvhNV7dIe3l8ARepOA1ABFK2OMypzb+Rb+nWQeo//yFz/28PmL63kdLiE72qmmQuzuPa5NXaV9pJ4JKw86QdLhGGpFIRH18Iugf3xLFwQEZqKYnblTUs7ftnTgW5r4HH492kCAwEAATANBgkqhkiG9w0BAQQFAAOBgQCsOD02WMoYcMR7Sqdb9oQyk7Nn4rQ5DBgZ5mxGGVzWxBZW/QON+Ir2j4KUjX1jalMvbHa9lnhPQmJiUed923rza7fvdRG2CDalbW0R3aPd5q0u3akP0/Ejb7z5o88heajCSgfRruvU+ZdOTT3Oe+RBQgw8VuzbLApPnXiehowYuA==</X509Certificate>

WS-Security 处理的最后阶段是验证 Web 服务请求者的数字证书。当使用数字证书方法时,每个 Web 服务请求者都必须有一个可信认证中心(Certificate Authority,CA)签署的数字证书。可信认证中心的定义不在本文的讨论范围之内,但通常是由业界接受的第三方认证中心(象 VeriSign 这样的公司)来充当这个角色,或者由 Web 服务提供者为他们的应用程序使用的证书充当认证中心这个角色。如果使用后一种方法的话,建议使用 Apache 的开放源代码 OpenSSL 工具箱或者使用 WebSphere Application Server 的 IKEYMAN 实用程序提供的基础数据证书支持。

我们的应用程序首次展示时,客户都选择了充当认证中心这个角色。因此,他们创建了自己的自签署 CA 证书。在任何 Web 服务进行交互之前,Web 服务请求者必须向 Web 服务提供者提供他们将在应用程序中使用的证书。在充当认证中心的同时,Web 服务提供者还签署这个证书并将它返还给 Web 服务请求者。

如上所述,Web 服务请求者在 SOAP 消息中包含了一个由 CA 签署的数字证书。数字签名验证过消息的完整性之后,就从消息中抽取出证书并使用 CA 的公共密钥验证这个证书。一旦完成了证书的验证,Web 服务请求者也就得到了认证,同时也完成了消息的 WS-Security 部分的处理。所有者就成功地对接收方进行了认证。

请注意:如果服务提供者后来自己不再充当认证中心,而使用一个被业界接受的、可信的第三方认证中心,验证代码的逻辑也无需改变。本案例中,在使用 Web 服务之前,Web 服务请求者需要获得一个由一家可信认证中心签发的证书。服务请求者会将这个第三方证书放在 SOAP 消息中。当服务提供者验证这个数字证书时,将使用第三方 CA 的公共密钥而不使用他们自己签署的 CA 密钥。本案例中,服务提供者已经和第三方认证中心确立了信任关系,并且相信 CA 在向用户签发证书前会对他们进行充分的认证。





回页首

WS-Security 与 WSDL

Web 服务的承诺之一就是能够松散地连结各个端点并且允许在 UDDI 目录中发布服务,这些 UDDI 目录可以在运行时被发现和动态调用。遗憾的是,在技术生命周期的这个阶段,SOAP 消息头中 WS-Security 的使用使我们无法做到这一点。今天的 Java 到 WSDL 发射器(Java to WSDL emitter)依然不能创建恰当描述 WS-Security 需求的 WSDL 文档。另外,即使他们能够创建,在现阶段,WebSphere Studio Application Developer 或者 Visual Studio .Net 之类的开发工具仍然不能生成处理服务的 WS-Security 方面的代理。

因此,Web 服务开发者在 2003 年初就需要在这一点上有意识地实现平衡。当使用 WS-Security 时,服务提供者必须要么提供合作伙伴可以调用的存根/代理来处理消息的 WS-Security 部分,要么为他们潜在的业务伙伴和客户手工传达 Web 服务的 WS-Security 需求。对于本文描述的这个基于 WS-Security 的项目,那些恰当签署消息并将 WS-Security 元素插入 SOAP 数据流的代理是为 Java 技术、COM 以及 .Net 客户机创建的。IBM 和其他公司的下一代 Web 服务开发工具应该能够处理 Web 服务的 WS-Security 元素,但开发者需要明白这是个可实现的处理但目前还处于手工处理阶段。





回页首

总结

本文描述了 2002 年开发并部署的一个基于因特网的 Web 服务应用程序。它被部署在 WebSphere Application Server 上并可被客户的业务伙伴使用。它通过用自身作为证据证明目前的开发工具和部署平台能够创建出安全的、任务关键的 Web 服务应用程序说明了 WS-Security 规范草案的稳定性和整体可行性。是的,在我们的客户案例中,需要一些非自动的、手工的步骤来处理 SOAP 消息的 WS-Security 元素,但是当对 WS-Security 的支持列入下一代 WSDL 规范,并且许多供应商的 Web 服务开发工具添加了这种支持时,它只会变得更好。

 

1. 引言

本规范提出了一套标准的 SOAP扩展,可以在构建安全的 Web 服务以实现完整性和机密性时使用。我们将这套扩展称为“Web 服务安全性语言(Web Services Security Language)”或“WS-Security”。

WS-Security 很灵活,它被设计成用来构建多种安全性模型(包括 PKI、Kerberos 和 SSL)的基础。WS-Security 特别为多安全性令牌、多信任域、多签名格式和多加密技术提供支持。

本规范提供了三种主要的机制:安全性令牌传播、消息完整性和消息机密性。这些机制本身并不提供完整的安全性解决方案。相反,WS-Security 是一种构件,它可以与其它 Web 服务扩展和更高级的特定于应用程序的协议联合使用,以适应多种安全性模型和加密技术。

这些机制可以独立使用(例如传送安全性令牌),或以紧密集成的方式使用(例如,对消息签名和加密,并提供与用于签名和加密的密钥相关的安全性令牌层次结构)。

本文档的推出紧接着 IBM 和 Microsoft 现有的 Web 服务安全性规范,包括 SOAP-SEC;Microsoft 的 WS-Security 和 WS-License;还有 IBM 的安全性令牌和加密文档。

请注意,第 1 部分是非标准的。

1.1. 目标和需求

WS-Security 的目标是使应用程序能构建安全的 SOAP消息交换。

本规范旨在提供一套可以用于构建一系列安全性协议的灵活的机制;换句话说,本规范刻意不去描述显式确定的安全性协议。

与每个安全性协议相同,要确保使用 WS-Security 构建的安全性协议不易受到各种形式的攻击,必须作出很多努力。

概括地说,本规范的重点就是描述一种为消息安全性准备的单消息安全性语言,这种消息安全性可以假定已经建立的会话、安全性环境和/或策略协议。

支持安全的消息交换需要的东西如下所示:

1.1.1. 需求

Web 服务安全性语言必须支持多种安全性模型。下面的清单表明了本规范的关键驱动性需求:

  • 用于认证或授权的多安全性令牌

  • 多信任域

  • 多加密技术

  • 端对端消息级安全性而非仅仅传输级安全性

1.1.2. 非目标

下面的主题超过了本文档的讨论范围:

  • 建立需要多交换的安全性环境或认证机制。

  • 密钥交换和派生出的密钥

  • 信任是如何建立或决定的。

1.2. 示例

下面的示例将说明一个带有用户名安全性令牌的消息:

(001) <?xml version="1.0" encoding="utf-8"?>(002)  <S:Envelope xmlns:S="http://www.w3.org/2001/12/soap-envelope"xmlns:ds="http://www.w3.org/2000/09/xmldsig#">(003)    <S:Header>(004)       <m:path xmlns:m="http://schemas.xmlsoap.org/rp/">(005)         <m:action>http://fabrikam123.com/getQuote</m:action>(006)         <m:to>http://fabrikam123.com/stocks</m:to>(007)          <m:id>uuid:84b9f5d0-33fb-4a81-b02b-5b760641c1d6</m:id>(008)       </m:path>(009)       <wsse:Securityxmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext">(010)         wsse:UsernameToken Id="MyID">(011)             <wsse:Username>Zoe</wsse:Username>(012)         </wsse:UsernameToken>(013)         <ds:Signature>(014)            <ds:SignedInfo>(015)               <ds:CanonicalizationMethodAlgorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>(016)               <ds:SignatureMethodAlgorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"/>(017)               <ds:Reference URI="#MsgBody">(018)                  <ds:DigestMethodAlgorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>(019)                  <ds:DigestValue>LyLsF0Pi4wPU...</ds:DigestValue>(020)               </ds:Reference>(021)            </ds:SignedInfo>(022)            <ds:SignatureValue>DJbchm5gK...</ds:SignatureValue>(023)            <ds:KeyInfo>(024)                <wsse:SecurityTokenReference>(025)                 <wsse:Reference URI="#MyID"/>(026)                </wsse:SecurityTokenReference>(027)            </ds:KeyInfo>(028)         </ds:Signature>(029)      </wsse:Security>(030)   </S:Header>(031)   <S:Body Id="MsgBody">(032)     <tru:StockSymbol xmlns:tru="http://fabrikam123.com/payloads">QQQ</tru:StockSymbol>(033)   </S:Body>(034) </S:Envelope>

开头两行将启动 SOAP 信封。行(003)启动与此 SOAP 消息相关的报头。行(004)到(008)指定如何路由此消息(如 WS-Routing中定义的那样)。

行(009)启动我们在本规范中定义的 <Security>报头。该报头包含预期接收方的安全性信息。该元素继续一直到行(029)为止。

行(010)到(012)指定与本消息相关的 安全性令牌。这样,它就定义了使用 <UsernameToken>的客户机的 用户名。请注意,我们在这里假定服务知道密码 — 换句话说,这是个共享的秘密。

行(013)到(028)指定数字签名。该签名确保了被签署元素的 完整性(也就是它们不被修改)。签名使用了 XML 签名规范。在本示例中,签名是根据从用户密码生成的密钥进行的;一般来说,应该使用更强大的签名机制(请参阅下面的 扩展示例)。

行(014)到(021)描述了数字签名。行(015)指定如何规范化(普通化)被签署的数据。

行(017)到(020)选择被签署的元素。行(017)特别指出 <S:Body> 元素被签署。在本示例中,只有消息主体被签署;一般来说,消息的附加元素(如部分路由报头)应该被包括在签名中(请参阅下面的 扩展示例)。

如 XML 签名规范中所定义,行(022)指定将被签署的标准化数据形式的签名值。

行(023)到(027)提供关于在何处能找到与此签名相关的 安全性令牌的 暗示。行(024)到(025)特别指出 安全性令牌可以在特定 URL 找到(拉出)。

行(031)到(033)包含 SOAP消息的 主体(有效负载)。





回页首

2. 符号和术语

这一部分指定在本规范中使用的符号、名称空间和术语。

2.1. 符号转换

本文档中的关键字“MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、“MAY”和“OPTIONAL”应该用 RFC2119 中描述的方式来解释。

名称空间 URI(常规形式“some-URI”)表示某种依赖应用程序或依赖环境的 URI,就象 RFC2396中定义的一样。

WS-Security 旨在与一般的 SOAP消息结构和消息处理模型共同工作,而 WS-Security 对于任何版本的 SOAP都应该是适用的。这里使用了当前的 SOAP1.2 名称空间 URI,以提供详细示例,但我们无意将此规范的适用性限制在单个版本的 SOAP中。

读者应该熟悉 Internet Security Glossary中的术语。

2.2. 名称空间

该规范的实现一定要使用的 XML 名称空间URI 是:

http://schemas.xmlsoap.org/ws/2002/04/secext



本文档中使用了下列名称空间:



前缀 名称空间 s http://www.w3.org/2001/12/soap-envelope ds http://www.w3.org/2000/09/xmldsig# xenc http://www.w3.org/2001/04/xmlenc# m http://schemas.xmlsoap.org/rp wsse http://schemas.xmlsoap.org/ws/2002/04/secext

2.3 术语

我们为本规范中使用的安全性术语提供了基本的定义。

声明声明是客户进行的一条陈述(例如名称、身份、密钥、组、特权、能力等)。

安全性令牌安全性令牌代表声明的集合。

已签署的安全性令牌签署的安全性令牌是由特定机关声明并加密签署的安全性令牌(例如 X.509 证书或 Kerberos 票据)。

图 1

图 1

所有权证明所有权证明信息是证明过程中用来说明发送方对信息的认识的数据,这些信息仅为安全性令牌的声明发送方所知。

完整性完整性是保证信息在传输过程中不被修改的过程。

机密性机密性是保护数据使得授权参与者或安全性令牌所有者才能够浏览数据的过程。

摘要摘要是八位流的加密校验和。

签名签名是所有权证明和摘要的加密绑定。这涵盖了基于对称密钥和基于公钥的签名。所以,并不总是能够达到不可抵赖性。

附件附件是一个一般术语,指与 SOAP 消息一起传递的附加数据,但不属于 SOAP 信封的一部分。





回页首

3. 保护质量

为了保护 SOAP消息的安全,您应该考虑两种类型的威胁:1) 消息可能被对手修改或阅读,或者 2) 对手可能将格式良好但缺乏适当安全性声明来保证处理过程的消息发送到服务。

为了理解这些威胁,我们定义了一个消息安全性模型。

3.1. 消息安全性模型

在本文档中,我们根据安全性令牌,与 签名组合在一起作为安全性令牌(密钥)的所有权声明,指定了一个抽象的 消息安全性模型

安全性令牌发出 声明,而 签名为确认发送者对密钥的认识提供了一种机制。同时, 签名能够用于“绑定”或“关联” 签名和 安全性令牌中的 声明(假定令牌已被信任)。请注意,这种绑定被限制在签名涉及的元素中。另外还要注意,本文档并不指定特殊的认证方法,它只是表明 安全性令牌可以被绑定到消息。

声明可以由被信任的机构签署或取消签署。一组被签署的声明一般由数字签署或被机构加密的 签署过的安全性令牌表示。 X.509证书(声明身份和公钥之间绑定)就是 签署过的安全性令牌的一个示例。签署过的 声明也可以被表示为对某机构的引用,目的是让接收方可以从被引用的机构“拉”出 声明。

如果发送方和接收方之间存在信任关系,没有签署的 声明也可以信任。举例来说,如果发送方和接收方使用信任连接,而且它们之间存在特殊的信任关系,那么没有签署的对发送方为 Bob 的声明来说,特定接收方也足以相信发送方确实是 Bob。

非签署 声明的一种特殊类型是 所有权证明。这种 声明将证明发送方具有可以被合适的 参与者验证的特定知识。举例来说,用户名/密码就是带这种类型 声明的 安全性令牌。 所有权证明声明有时候与其它 安全性令牌联合使用来证明发送者的声明。请注意,用于消息 完整性的数字 完整性也可以用作 所有权证明声明,尽管我们在本规范中不考虑把这种数字 签名作为一种 安全性令牌的情况。 您应该注意,这种安全性模型本身就易于遭受多安全性攻击。请参阅 安全性注意事项部分了解其它细节。

3.2. 消息保护

保护消息内容免遭拦截( 机密性)或非法修改( 完整性)是主要的安全性问题。本规范提供了一种通过对消息主体、报头、附件或它们的任何组合(或部分)进行加密和/或数字签署来保护消息的方法。

消息 完整性是通过同时利用 XML 签名和 安全性令牌来确保消息在传输过程中不被修改而实现的。 完整性机制旨在支持多 签名(可能是多参与者进行的),而且可以扩展为支持其它 签名格式。

消息 机密性同时利用 XML 加密和 安全性令牌来保持部分 SOAP消息是 机密的。加密机制旨在支持多参与者的其它加密过程和操作。

3.3. 丢失或不合适的声明

消息接收方应该拒绝签名无效、 声明丢失或不合适的消息,因为这种消息是非授权(或格式错误)的消息。本规范通过将零或多个 安全性令牌与消息关联,为消息发送者 声明安全性属性提供了一种灵活的方法。安全性 声明的一个示例是发送方的身份;发送方可以 声明他是 Bob,也就是某公司的职员,从而有发送消息的权力。





回页首

4. 安全性元素

<Security> 报头块提供了一种机制,用来附加定位在特定接收方( SOAP 参与者)的有关安全性的信息。这可能是消息最终接收方或中介体。因此,该报头块可能在 SOAP消息中多次被提出。消息路径上的中介体可能向已有的 <Security> 报头块添加一个或多个新的子元素,如果它们的目标是同一个 SOAP节点,否则中介体可能为其它目标添加一个或多个新的报头。

如上所述,如果消息报头定位在分开的接收方上,消息就可能有多个 <Security> 报头块。然而,只有一个 <Security> 报头块可以省略 S:actor 属性,两个 <Security> 报头块不能有相同的 S:actor 值。定位在不同接收方上的消息安全性信息必须出现在不同的 <Security> 报头块中。没有指定的 S:actor 的 <Security> 报头块可以被任何人使用,但绝不能在 WS-Routing决定的最终点之前删除。

因为元素被添加到 <Security> 报头块中,所以在已有的元素中应该预先考虑它们。这样,<Security> 报头块表示消息发送方用来创建消息所采取的签名和加密步骤。这种预先考虑的规则将确保接收的应用程序可以按子元素在 <Security> 报头块中出现的顺序处理它们,因为子元素之间不会有向前依赖性。请注意,该规范并不强制任何处理子元素的特定顺序。接收的应用程序可以使用任何所需的策略。

当子元素引用另一个子元素中带有的密钥时(例如引用包含用于签名的 X.509证书的二进制安全性令牌子元素的签名子元素),应该在将添加的使用密钥的子元素之后预先考虑包含密钥的安全性令牌,这样密钥材料就会在使用密钥的子元素之前出现。

下面举例说明该报头的句法:

<S:Envelope><S:Header>...<Security S:actor="..." S:mustUnderstand="...">...</Security>...</S:Header>...</S:Envelope>

下面将描述上面示例列出的属性和元素:

/Security

这是向接收方传送与安全性相关的消息信息的报头块。

/Security/@S:actor

该属性允许标识一个特定的 SOAP参与者。该属性不是必需的;然而,不能有两个报头块的实例可以省略参与者或指定相同的参与者。

/Security/{any}

这是一个允许根据模式传送不同(可扩展)类型的安全性信息的扩展性机制。

/Security/@{any}

这是一种允许根据模式向报头添加另外属性的扩展性机制。

下面的子节部分将概述要在 <Security> 报头内使用的新的和已有的元素。

4.1. UsernameToken 元素

我们引入 <UsernameToken> 是作为验证用户名和可选密码信息的方式。

下面举例说明该元素的句法:

<UsernameToken Id="..."><Username>...</Username><Password Type="...">...</Password></UsernameToken>

下面将描述上面示例中列出的属性和元素:

/UsernameToken

该元素用于发送基本认证信息。

/UsernameToken/@Id

该 安全性令牌的一个字符串标记。

/UsernameToken/Username

这个所需的元素指定认证方的用户名。

/UsernameToken/Username/@{any}

这是一种允许根据模式向报头添加另外属性的扩展性机制。

/UsernameToken/Password

这个可选元素提供密码信息。我们建议:只有在使用安全的传输时才传送该元素。

/UsernameToken/Password/@Type

这个可选属性将指定所提供的密码的类型。下面的表将说明预定义类型:



值 描述 wsse:PasswordText(缺省) 用户名的实际密码。 wsse:PasswordDigest 用户名密码摘要。值为 UTF8 编码的密码的 base64 编码的 SHA1 散列值。

/UsernameToken/Password/@{any}

这是一种允许根据模式向报头添加另外属性的扩展性机制。

/UsernameToken/{any}

这是一种允许根据模式传送各种不同(可扩展)类型的安全性信息的扩展性机制。

/UsernameToken/@{any}

这是一种允许根据模式向报头添加其它属性的扩展性机制。

下面举例说明该元素的使用:

<S:Envelope xmlns:S="http://www.w3.org/2001/12/soap-envelope"xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext"><S:Header>...<wsse:Security><wsse:UsernameToken><wsse:Username>Zoe</wsse:Username><wsse:Password>ILoveDogs</wsse:Password></wsse:UsernameToken></wsse:Security>...</S:Header>...</S:Envelope>

4.2. 编码二进制安全性令牌

任何基于 XML 的安全性令牌都可以在 <Security> 报头中指定。然而,二进制(例如 X.509证书和 Kerberos票据)或其它非 XML 格式都需要特殊的编码格式进行包含。

一个二进制安全性令牌有两个用于解释自身的属性。ValueType 属性表明安全性令牌是什么,比如说 Kerberos票据。EncodingType 表明安全性令牌如何被编码,例如使用 Base64Binary。

BinarySecurityToken 元素定义二进制编码的安全性令牌。编码过程用 EncodingType 属性指定,值类型和空间用 ValueType 属性指定。

下面是句法的大概情况:

<BinarySecurityToken Id=...EncodingType=...ValueType=.../>

下面将描述上面示例中列出的属性和元素:

/BinarySecurityToken

该元素用于包括二进制编码的安全性令牌。

/BinarySecurityToken/@Id

该 安全性令牌的一个可选字符串标签。

/BinarySecurityToken/@ValueType

ValueType 属性用于表明编码二进制数据(例如 X.509证书)的“值空间”。ValueType 属性允许定义编码二进制数据的值类型和空间的限定名。该属性用 XML 名称空间时是可扩展的。

/BinarySecurityToken/@EncodingType

EncodingType 属性用于使用 QName 表明二进制数据的编码格式(例如 wsse:Base64Binary)。我们引入这个新属性是因为当前的情况使得在 XML 模式内对混合的简单和复杂类型进行派生变得困难。解释 EncodingType 属性是为了表明元素的编码格式。下面的编码格式是预定义的:



QName 描述 wsse:Base64Binary XML Schemabase 64 编码 wsse:HexBinary XML Schema十六进制编码

/BinarySecurityToken/@{any}

这是一种允许根据模式添加其它属性的扩展性机制。

下面的值空间是为 @ValueType 定义的:



QName 描述 wsse:X509v3 X.509v3 证书 wsse:Kerberosv5TGT Kerberos的 5.3.1 节中定义的 Kerberosv5 票据。这个 ValueType 在票据为赋予票据的票据(ticket granting ticket,TGT)时使用。 wsse:Kerberosv5ST Kerberos的 5.3.1 节中定义的 Kerberosv5 票据。这个 ValueType 在票据为服务票据(service ticket,ST)时使用。

请注意, XML 签名也提供对 X.509证书编码的机制。带有 ValueType="wsse:X509v3" 的 BinarySecurityToken 可以在由于编码而需要灵活性的时侯使用。另一方面,使用 ds:KeyInfo 可以在使用情况中提供另外的灵活性。

下面举例说明 BinarySecurityToken 的使用:

<wsse:BinarySecurityTokenxmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext"Id="myToken"ValueType="wsse:X509v3"EncodingType="wsse:Base64Binary">MIIEZzCCA9CgAwIBAgIQEmtJZc0...</wsse:BinarySecurityToken>

当签名中使用 <BinarySecurityToken> 时(也就是说从 <ds:Signature> 元素引用它),应该注意规范算法(例如 专用 XML 规范化(Exclusive XML Canonicalization))不允许对属性或元素值中 QName 的名称空间前缀进行非授权的替换。如果该令牌不带有签署密钥(而且它因此没有加密地绑定到 签名上),我们就特别推荐在 <BinarySecurityToken> 元素内部声明这些名称空间前缀。举例来说,如果我们希望对前面的示例签名,那么我们就需要加入使用的名称空间定义。下面的示例中使用了一个定制的 ValueType。因此,这个 ValueType 的名称空间定义就包括在 <BinarySecurityToken> 元素中。请注意,与 wsse 在编码类型和元素中的使用相同,这里也包括它的定义。

<wsse:BinarySecurityTokenxmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext"Id="myToken"ValueType="x:MyType" xmlns:x="http://fabrikam123.com/x"EncodingType="wsse:Base64Binary">MIIEZzCCA9CgAwIBAgIQEmtJZc0...</wsse:BinarySecurityToken>

当 Kerberos票据作为签名密钥引用时, 签名算法应该是一个散列的消息认证码。我们特别推荐使用 HMAC-SHA1( XML 签名所需),它的票据中的会话密钥作为共享的密钥使用。

4.3. SecurityTokenReference 元素

安全性令牌传送一组 声明。有时候这些声明驻留在其它某些地方,需要接收的应用程序将它们“拉”出来。<SecurityTokenReference> 元素提供了一种引用 安全性令牌的可扩展机制。

下面说明该元素的句法:

<SecurityTokenReference Id="..."><Reference URI="..."/></SecurityTokenReference>

下面将描述上面定义的元素:

/SecurityTokenReference

该元素提供对安全性令牌的引用。

/SecurityTokenReference/@Id

此 安全性令牌引用的一个字符串标签

/SecurityTokenReference/Reference

该元素用于标识定位安全性令牌的 URI 位置。

/SecurityTokenReference/Reference/@URI

该属性指定在何处查找安全性令牌的 URI。

/SecurityTokenReference/{any}

这是一种允许根据模式传送不同(可扩展)类型的安全性信息的扩展性机制。

/SecurityTokenReference/@{any}

这是一种允许根据模式向报头添加其它属性的扩展性机制。

下面举例说明该元素的使用:

<wsse:SecurityTokenReferencexmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext"><wsse:ReferenceURI="http://www.fabrikam123.com/tokens/Zoe#X509token"/></wsse:SecurityTokenReference>

该元素还可以被用作 <ds:KeyInfo> 的一个直接子元素,用来表明从其它某些地方的安全性令牌检索密钥信息的暗示。在使用 XML 签名和 XML 加密时,我们特别推荐将 <SecurityTokenReference> 元素放在 <ds:KeyInfo> 内来引用用于签名或加密的 安全性令牌。

4.4. ds:KeyInfo

对于某些密钥类型(如 X.509 证书)来说,<ds:KeyInfo> 元素(来自 XML 签名)和 <BinarySecurityToken> 元素都可以用于传送密钥信息。<ds:KeyInfo> 元素虑及了不同密钥类型和将来的扩展性。然而,在本规范中,如果密钥类型在 第 4.2 节中很好地定义过,那么使用 <BinarySecurityToken> 就是我们推荐用于传送密钥信息的方式。

下面的示例说明使用该元素获取命名过的密钥的过程:

<ds:KeyInfo Id="..." xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:KeyName>CN=Hiroshi Maruyama, C=JP</ds:KeyName></ds:KeyInfo>

4.5. ds:Signature

消息发送方可能希望让消息接收方能够决定消息是否在传输过程中更改过,并验证消息是由特定 安全性令牌持有人发送的。

当 XML 签名与 <SecurityTokenReference> 元素同时使用时,消息签署人的 安全性令牌可能被关联,而安全性令牌声明和消息之间会以应用程序估计的方式产生映射。

由于某些 SOAP报头的不稳定性,发送者绝不能使用 XML 签名中定义的 封装的签名转换。相反,消息应该显式包括要签署的所需元素。类似地,发送方绝不能使用 XML 签名中定义的 封装签名

本规范虑及多个签名附加在消息中的情况,这时每个签名都引用不同、甚至重叠的消息部分。这对于很多分布式应用程序都是很重要的,在这些应用程序程序中,消息要经过多个处理阶段。举例来说,发送方可能提交一个包含 orderID 报头的订单。发送方签署 orderID 报头和请求的主体(订单的内容)。当订单处理子系统收到这个时,它可能向报头插入一个 shippingID。发出订单的子系统然后会签署(最少)orderID 和 shippingID,可能还有请求主体。然后当运输部门处理和交付该订单后,可能会附加一个 shippedInfo 报头。运输部门将签署(最少)shippedInfo 和 shippingID,可能还有请求主体,然后将消息转发给记帐部门进行处理。记帐部门可以验证签名并决定订单的有效信任链,以及各个角色所做的事情。

所有依从的实现都必须能够处理 <ds:Signature> 元素。

4.5.1. 算法

WS-Security 规范建立在 XML 签名的基础之上,因此具有与 XML 签名规范中指定的相同的算法需求。

下面的表描述了 WS-Security 推荐的其它算法:



算法类型 算法 算法 URI 规范化 专用 XML 规范化 http://www.w3.org/2001/10/xml-exc-c14n 转换 XML 解密转换(XML Decryption Transformation) http://www.w3.org/2001/04/decrypt

专用 XML 规范化算法使用“预先存在的签名”解决了一般规范化在名称空间有漏洞时存在的缺陷。

最后,如果发送方希望在加密前签署消息,他们应该使用 XML 签名的解密转换( Decryption Transformation for XML Signature)。

4.5.2. 签署消息

<Security> 报头块用于在 SOAP信封中传送符合 XML 签名规范的签名,为了签署 SOAP信封中的一个或多个元素。<Security> 报头块中的单独的 SOAP信封中可以添加多个签名条目。发送方应该注意签署消息的所有重要元素,但一定要注意创建的策略不会签署消息在传送过程中可能被合理更改的部分。

SOAP应用程序必须满足下面的条件:

  1. 应用程序必须能够处理 XML 签名规范中定义的所需元素。

  2. 要向 <Security> 报头块添加签名,应该预先考虑与 XML 签名规范一致的 <ds:Signature> 元素,下来才是已有的 <Security> 报头块的内容。也就是说,新信息要在旧信息之前(优先)。签名中包含的所有 <ds:Reference> 元素都应该引用包含它的 SOAP信封内(或附件中)的资源。

如 XML 签名规范中所示, XPath过滤可以用于指定将签署的对象。然而,因为 SOAP消息交换模型允许中介体应用程序修改信封(如添加或删除报头块), XPath过滤在消息传递之后并不总能得到相同对象。使用 XPath过滤时应该注意避免因为这种修改导致后来的验证失败。

中介体应用程序修改的问题不仅仅在 XPath 处理中才会发生。由于规范化和 分类的原因,数字签名是这种关系的特别脆弱的例子。如果消息处理整体要保持健壮,中介体必须注意转换不会出现在数字签名组件的范围中。

鉴于和名称空间有关的安全性注意事项,本规范强烈推荐您使用提供相同或更多保护的“ 专用 XML 规范化(Exclusive XML Canonicalization)”算法或其它标准化算法。

4.5.3. 验证完整性

如果发生下列情况,<Security> 报头块中 <ds:Signature> 条目的验证就会失败:

  1. 条目内容的句法不遵守本规范,或者

  2. 根据 XML 签名的核心验证,条目中包含的 签名的验证失败,或者

  3. 应用自己的信任策略的应用程序因为某种原因拒绝消息(例如, 签名由非信任的密钥创建 — 验证前两个步骤只会执行对 签名加密的验证)。

如果签名验证失败,那么应用程序可能会使用 第 6 节中定义的错误代码向发送者报告失败情况。

4.5.4. 示例

下面的样本消息举例说明了完整性和安全性令牌的使用。对于本示例,我们使用了假定的“RoutingTransform”,它选择不变的路由报头以及消息主体。

<?xml version="1.0" encoding="utf-8"?><S:Envelope xmlns:S="http://www.w3.org/2001/12/soap-envelope"xmlns:ds="http://www.w3.org/2000/09/xmldsig#"xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext"xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><S:Header><m:path xmlns:m="http://schemas.xmlsoap.org/rp"><m:action>http://fabrikam123.com/getQuote</m:action><m:to>http://fabrikam123.com/stocks</m:to><m:from>mailto:johnsmith@fabrikam123.com</m:from><m:id>uuid:84b9f5d0-33fb-4a81-b02b-5b760641c1d6</m:id></m:path><wsse:Security><wsse:BinarySecurityTokenValueType="wsse:X509v3"EncodingType="wsse:Base64Binary"Id="X509Token">MIIEZzCCA9CgAwIBAgIQEmtJZc0rqrKh5i...</wsse:BinarySecurityToken><ds:Signature><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><ds:Reference><ds:Transforms><ds:Transform Algorithm="http://...#RoutingTransform"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>EULddytSo1...</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>BL8jdfToEb1l/vXcMZNNjPOV...</ds:SignatureValue><ds:KeyInfo><wsse:SecurityTokenReference><wsse:Reference URI="#X509Token"/></wsse:SecurityTokenReference></ds:KeyInfo></ds:Signature></wsse:Security></S:Header><S:Body><tru:StockSymbol xmlns:tru="http://fabrikam123.com/payloads">QQQ</tru:StockSymbol></S:Body></S:Envelope>

4.6. 子元素加密

本规范允许通过发送方和接收方共享的通用对称密钥或消息中带有的加密形式的密钥,对消息主体块、报头块、任意这些子结构和附件的组合进行加密。

为了实现这种灵活性,我们利用了 XML 加密(XML Encryption)标准。我们将特别描述如何在 <Security> 报头块中使用三个元素(下面列出的和 XML 加密中定义的)。当发送方或中介体使用 XML 加密对部分 SOAP消息加密时,它们会向 <Security> 报头块添加子元素。此外,加密方还必须预先考虑在 <Security> 报头块中使用子元素作为应该对加密部分解密的目标接收方。组合加密部分消息和添加其中一个引用加密部分的子元素的过程以后就被称为 加密步骤。子元素应该有足够信息,好让接收方可以识别消息的那些部分要由接收方解密。

4.6.1. xenc:ReferenceList

在加密 SOAP消息内的元素或元素内容时,您可以使用 XML 加密的 <xenc:ReferenceList> 元素来创建加密部分的证明,它被表示为信封内的 <xenc:EncryptedData> 元素。这个加密步骤要加密的元素或元素内容必须根据 XML 加密由对应的 <xenc:EncryptedData> 替换。该加密步骤创建的所有 <xenc:EncryptedData> 元素都应该列在 <xenc:ReferenceList> 元素的 <xenc:DataReference> 元素中。

尽管在 XML 加密中,<xenc:ReferenceList> 最初被设计为在 <xenc:EncryptedKey> 元素中使用(这表明所有被引用的 <xenc:EncryptedData> 元素都用同一个密钥加密),本规范允许同一个 <xenc:ReferenceList> 引用的 <xenc:EncryptedData> 元素在不同步骤中加密。每个加密密钥都可以在 <xenc:EncryptedData> 内的 <ds:KeyInfo> 中指定。

<xenc:ReferenceList> 子元素有用的典型情况是,发送方和接收方都使用共享的秘密密钥。下面举例说明了这个子元素的使用:

<S:Envelopexmlns:S="http://www.w3.org/2001/12/soap-envelope"xmlns:ds="http://www.w3.org/2000/09/xmldsig#"xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext"xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><S:Header><wsse:Security><xenc:ReferenceList><xenc:DataReference URI="#bodyID"/></xenc:ReferenceList></wsse:Security></S:Header><S:Body><xenc:EncryptedData Id="bodyID"><ds:KeyInfo><ds:KeyName>CN=Hiroshi Maruyama, C=JP</ds:KeyName></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>...</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData></S:Body></S:Envelope>

4.6.2. xenc:EncryptedKey

当加密步骤涉及到使用密钥(它接着会被接收方的密钥加密并嵌入到消息中)加密 SOAP信封中的元素或元素内容时,就可以使用 <xenc:EncryptedKey> 来传送这种加密密钥了。该子元素应该有一个证明(也就是 <xenc:ReferenceList> 元素),用来让接收方了解要用这个密钥(如果存在的话)解密的部分。要用这个加密步骤加密的元素或元素部分必须根据 XML 加密由对应的 <xenc:EncryptedData> 替换。所有这个步骤创建的 <xenc:EncryptedData> 元素都应该列在该子元素内的 <xenc:ReferenceList> 元素中。

这种构建方法在通过随机生成的对称密钥(该密钥接着由接收方的公共密钥加密)完成加密时很有用。下面举例说明了这个元素的使用:

<S:Envelopexmlns:S="http://www.w3.org/2001/12/soap-envelope"xmlns:ds="http://www.w3.org/2000/09/xmldsig#"xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext"xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><S:Header><wsse:Security><xenc:EncryptedKey><xenc:EncryptionMethod Algorithm="..."/><ds:KeyInfo><ds:KeyName>CN=Hiroshi Maruyama, C=JP</ds:KeyName></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>...</xenc:CipherValue></xenc:CipherData><xenc:ReferenceList><xenc:DataReference URI="#bodyID"/></xenc:ReferenceList></xenc:EncryptedKey></wsse:Security></S:Header><S:Body><xenc:EncryptedData Id="bodyID"><ds:KeyInfo><ds:KeyName>CN=Hiroshi Maruyama, C=JP</ds:KeyName></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>...</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData></S:Body></S:Envelope>

4.6.3. xenc:EncryptedData

在某些情况下,有关安全性的信息是以完全加密的形式提供的,或者加密时非 XML 附件会被加密。 XML 加密的 <xenc:EncryptedData> 元素可以用在这种情况下。对加密附件的每个部分来说,都需要一个加密步骤;那就是,对于每个要加密的附件,都必须遵守下列规则添加一个 <xenc:EncryptedData> 子元素(请注意,步骤 2 到 4 只有在 MIME 类型由附件使用时才适用)。

  1. 附件的内容必须被加密八位串代替。

  2. 被替换的 MIME 部分的媒体类型必须是 application/octet-stream。

  3. 附件的原始媒体类型必须在 <xenc:EncryptedData> 元素的 MimeType 属性中声明。

  4. 加密的 MIME 部分必须由 <xenc:CipherReference> 元素引用,其中 URI 指向 MIME 部分,cid: 为 URI 的模式组件。

下面举例说明了使用该元素表明加密附件的方法:

<S:Envelopexmlns:S="http://www.w3.org/2001/12/soap-envelope"xmlns:ds="http://www.w3.org/2000/09/xmldsig#"xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext"xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><S:Header><wsse:Security><xenc:EncryptedData MimeType="image/png"><xenc:EncryptionMethod Algorithm="foo:bar"/><ds:KeyInfo><ds:KeyName>CN=Hiroshi Maruyama, C=JP</ds:KeyName></ds:KeyInfo><xenc:CipherData><xenc:CipherReference URI="cid:image"/></xenc:CipherData></xenc:EncryptedData></wsse:Security></S:Header><S:Body> </S:Body></S:Envelope>

4.6.4. 处理规则

使用上述其中一种子元素对 SOAP消息加密的部分或附件必须符合 XML 加密规范。加密的 SOAP消息必须还是一个有效的 SOAP信封。消息的创建者绝不能加密 <S:Envelope>、<S:Header> 或 <S:Body> 元素,但可以加密 <S:Header> 或 <S:Body> 元素的子元素。如果它们的目标都是同一个接收方,那么就可以向单独的 <Security> 报头块添加多个步骤的加密。

当要加密 SOAP信封中的元素或元素内容(例如 <S:Body> 的内容)时,它必须根据 XML 加密由 <xenc:EncryptedData> 替换,而且它应该从此加密步骤创建的 <xenc:ReferenceList> 元素引用。此规范允许在附件中存放加密八位流。举例来说,如果 <S:Body> 元素内出现的 <xenc:EncryptedData> 有引用附件的 <xenc:CipherReference>,那么解密八位流就替换 <xenc:EncryptedData>。然而,如果 <enc:EncryptedData> 的位置在 <Security> 报头块中,而它引用附件,那么解密八位流就必须替换附件中的加密八位流。

加密

创建符合此规范的加密 SOAP消息的一般步骤(非标准化的)如下所示(请注意,我们推荐使用 <xenc:ReferenceList>)。

  1. 创建新的 SOAP信封。

  2. 根据加密类型,在 <Security> 报头块中创建 <xenc:ReferenceList> 子元素、<xenc:EncryptedKey> 子元素或 <xenc:EncryptedData> 子元素(请注意,SOAP “actor”和“mustUnderstand”属性是否不同,不同就需要一个新的报头表)。

  3. 定位要加密的数据项,也就是 XML 元素、目标 SOAP 信封中的元素内容和附件。

  4. 如下所示加密数据:对于目标 SOAP信封中的每个 XML 元素或元素内容来说,根据 XML 加密规范的处理规则进行加密。每个已选择的原始元素或元素内容都由最后的 <xenc:EncryptedData> 元素删除和替换。对附件来说,内容则必须由加密的密码数据替换,如 章节 4.5.3.中所示。

  5. <xenc:EncryptedData> 元素中可选的 <ds:KeyInfo> 可以引用另一个 <ds:KeyInfo> 元素。请注意,如果加密是基于附加的安全性令牌的,那么就应该向 <ds:KeyInfo> 元素添加一个 <SecurityTokenReference> 元素以便于定位它。

  6. 创建一个引用生成的 <xenc:EncryptedData> 元素的 <xenc:DataReference> 元素。向 <xenc:ReferenceList> 添加 <xenc:DataReference>。

解密

当收到带有加密报头条目的 SOAP信封时,对于每个加密报头来说都应该进行下面的一般步骤(非标准的):

  1. 定位要解密的 <xenc:EncryptedData> 项(可能使用 <xenc:ReferenceList>)。

  2. 如下进行解密:对于目标 SOAP信封中的每个元素,根据 XML 加密规范的处理规则和上面列出的处理规则进行解密。

  3. 如果解密数据是附件的一部分而且使用了 MIME 类型,那么将附件的 MIME 类型改为原始 MIME 类型(如果存在)。

如果因为某种原因解密失败,应用程序就可以使用 第 6 节中定义的错误代码向发送方报告失败情况。





回页首

5. 扩展示例

下面的样本消息举例说明了安全性令牌、签名和加密的使用。对于本示例,我们使用了假定的“RoutingTransform”,它将选择不可变的路由报头以及消息主体。

(001) <?xml version="1.0" encoding="utf-8"?>(002) <S:Envelope xmlns:S="http://www.w3.org/2001/12/soap-envelope"xmlns:ds="http://www.w3.org/2000/09/xmldsig#"xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext"xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">(003)   <S:Header>(004)      <m:path xmlns:m="http://schemas.xmlsoap.org/rp/">(005)         <m:action>http://fabrikam123.com/getQuote</m:action>(006)         <m:to>http://fabrikam123.com/stocks</m:to>(007)         <m:from>mailto:johnsmith@fabrikam123.com</m:from>(008)         <m:id>uuid:84b9f5d0-33fb-4a81-b02b-5b760641c1d6</m:id>(009)      </m:path>(010)      <wsse:Security>(011)         <wsse:BinarySecurityTokenValueType="wsse:X509v3"Id="X509Token"EncodingType="wsse:Base64Binary">(012)         MIIEZzCCA9CgAwIBAgIQEmtJZc0rqrKh5i...(013)         </wsse:BinarySecurityToken>(014)         <xenc:EncryptedKey>(015)             <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>(016)             <ds:KeyInfo>(017)               <ds:KeyName>CN=Hiroshi Maruyama, C=JP</ds:KeyName>(018)             </ds:KeyInfo>(019)             <xenc:CipherData>(020)                <xenc:CipherValue>d2FpbmdvbGRfE0lm4byV0...(021)                </xenc:CipherValue>(022)             </xenc:CipherData>(023)             <xenc:ReferenceList>(024)                 <xenc:DataReference URI="#enc1"/>(025)             </xenc:ReferenceList>(026)         </xenc:EncryptedKey>(027)         <ds:Signature>(028)            <ds:SignedInfo>(029)               <ds:CanonicalizationMethodAlgorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>(030)               <ds:SignatureMethodAlgorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>(031)               <ds:Reference>(032)                  <ds:Transforms>(033)                     <ds:TransformAlgorithm="http://...#RoutingTransform"/>(034)                     <ds:TransformAlgorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>(035)                  </ds:Transforms>(036)                  <ds:DigestMethodAlgorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>(037)                  <ds:DigestValue>LyLsF094hPi4wPU...(038)                   </ds:DigestValue>(039)               </ds:Reference>(040)            </ds:SignedInfo>(041)            <ds:SignatureValue>(042)                     Hp1ZkmFZ/2kQLXDJbchm5gK...(043)            </ds:SignatureValue>(044)            <ds:KeyInfo>(045)                <wsse:SecurityTokenReference>(046)                    <wsse:Reference URI="#X509Token"/>(047)                </wsse:SecurityTokenReference>(048)            </ds:KeyInfo>(049)         </ds:Signature>(050)      </wsse:Security>(051)   </S:Header>(052)   <S:Body>(053)      <xenc:EncryptedDataType="http://www.w3.org/2001/04/xmlenc#Element"Id="enc1">(054)         <xenc:EncryptionMethodAlgorithm="http://www.w3.org/2001/04/xmlenc#3des-cbc"/>(055)         <xenc:CipherData>(056)            <xenc:CipherValue>d2FpbmdvbGRfE0lm4byV0...(057)            </xenc:CipherValue>(058)         </xenc:CipherData>(059)      </xenc:EncryptedData>(060)   </S:Body>(061) </S:Envelope>

让我们来回顾本示例中一些关密钥的部分:

行(003)到(051)包含 SOAP 消息报头。

行(004)到(009)指定 消息路由信息(如 WS-Routing 定义的)。在本示例中,我们发送消息到 http://fabrikam123.com/stocks 服务,请求“getQuote”操作。

行(010)到(050)表示 <Security> 报头块。它包含消息的与安全性相关的信息。

行(011)到(013)指定与消息关联的 安全性令牌。在本示例中,它指定按 Base64 编码的 X.509证书。行(012)指定该证书的实际 Base64 编码。

行(014)到(026)指定用于加密消息主体的密钥。因为这是一个对称密钥,所以它是以加密形式传送的。行(015)定义用于加密密钥的算法。行(016)到(018)指定用于加密对称密钥的密钥的名称。行(019)到(022)指定对称密钥实际的加密形式。行(023)到(025)识别消息中使用该对称密钥的加密块。在本示例中,它只用于加密消息主体(Id="enc1")。

行(027)到(047)指定数字签名。在本示例中,签名是基于 X.509证书的。行(028)到(040)表明签署什么。行(029)表明规范化算法(本示例中是排它的)。行(030)表明签名算法(在本示例中是 sha1 上的 rsa)。

行(031)到(039)标识正在被签署的消息部分。行(033)特别标识"转换"。这个假定的转换将选择路由报头和消息主体不变的部分。行(034)指定行(033)所选择的消息部分上要使用的规范化算法。行(036)表明规范化数据上的分类算法使用。行(037)指定规范化数据上的指定算法得出的分类值。

行(041)到(043)表明实际的签名值 — 在行(042)指定。

行(044)到(048)表明用于签名的密钥。在本示例中,它是消息中包括的 X.509证书。行(046)提供对行(011)到(013)的 URI 链接。

消息主体是由行(052)到(060)表示的。

行(053)到(059)表示加密的元数据和使用 XML 加密的消息主体的形式。行(053)表明“元素值”将被替换,并标识加密。行(054)指定加密算法 — 在本示例中为 Triple-DES。行(055)到(058)包含实际的密码文本(也就是加密的结果)。请注意,我们不包括对密钥的引用作为引用加密的密钥 — 行(024)。





回页首

6. 错误处理

在很多情况下,处理安全性信息时都会出现 错误。例如:

  • 无效或不支持的安全性令牌、签名或加密类型

  • 无效、非授权或不可授权的安全性令牌

  • 无效签名

  • 解密失败

  • 所引用的安全性令牌无法使用。

这些错误可以分为两 :不支持的和失败的。对于不支持的错误情况来说,接收者可以提供响应,告知发送者支持的格式等等。对于失败的错误来说,接收者可以选择不响应,因为这可以算是拒绝服务(Denial of Service,DOS)或加密攻击的一种形式。我们结合签名和加密失败来减少某些类型的攻击。

如果失败返回到发送者,那么必须使用 SOAP的“错误(Fault)”机制来报告错误。下面的表描述了预定义的安全性错误代码。错误的“不支持”类为:



出现的错误 错误代码 提供了不支持的令牌 wsse:UnsupportedSecurityToken 使用了不支持的签名或加密算法 wsse:UnsupportedAlgorithm

错误的“失败”类为:



出现的错误 错误代码 处理 <Security> 报头时发现错误。 wsse:InvalidSecurity 提供了无效的安全性令牌 wsse:InvalidSecurityToken 安全性令牌无法被验证或授权 wsse:FailedAuthentication 签名或解密是无效的 wsse:FailedCheck 引用的安全性令牌无法检索 wsse:SecurityTokenUnavailable





回页首

7. 安全注意事项

强烈推荐消息包含数字化签署元素,以允许消息接收者在消息通过开放网络进行交换的时候检测消息的重播。这些元素可能是消息的一部分或从其它 SOAP扩展定义的报头的一部分。四种典型的方式是:

  • 时间戳

  • 序列号

  • 有效期

  • 消息相关

本规范定义了 XML 签名和 XML 加密在 SOAP报头中的使用。作为保证 SOAP消息的安全的构件之一,它常常与其它安全技术联合使用。数字签名需要在其它安全机制的上下文中被理解,也需要在对实体的可能威胁的上下文中被理解。

仅仅数字签名并不提供消息认证。别人可以记录一条签名消息并将它重发(一个重演攻击)。为了预防这种类型的攻击,数字签名必须结合一种适当的办法来确保消息的唯一性,例如,时间戳或序列号(请参阅前面的部分了解更多细节)。

当用数字签名来验证发送方的身份时,发送者必须证明它拥有私钥。实现这一点的一种办法是使用问询-响应(challenge-response)类型的协议。这类协议已超出本文档的范围。

为了这个目标,开发者可以把时间戳、有效期和序列号附加到消息上。

实现者还应意识到,所有的安全问题都是普遍地使用数字签名和特殊地使用 XML 签名的结果。当要在基于数字签名的应用程序中构建信任时,还必须结合其它的技术(如证书评估),但这些已超出本文档的范围。

请求者应使用数字签名来签署不包含签名(或其它保护机制)的安全性令牌,以确保它们在传输中未被更改。

此外,如在 XML 加密中所述,我们注意到了在公共数据项上同时使用签署和加密可能会带来一些加密薄弱环节。例如,加密数字化签名数据,同时使数字签名不受攻击,可能会允许明文猜测攻击。应用程序设计者应该小心谨慎,不要引入这样的薄弱环节。





回页首

8. 致谢

本规范的制定是许多个人和团体共同努力的结果,包括:

Bob Blakley,IBM

Allen Brown,Microsoft

Kelvin Lawrence,IBM

Scott Konersmann,Microsoft

David Melgar,IBM





回页首

9. 参考资料

[DIGSIG]
信息类 RFC 2828, “Internet Security Glossary”,2000 年 5 月。
[Kerberos]
J. Kohl 和 C. Neuman,“ The Kerberos Network Authentication Service(V5),”RFC 1510,1993 年 9 月。
[KEYWORDS]
S. Bradner,“ Key words for use in RFCs to Indicate Requirement Levels,”RFC 2119,哈佛大学,1997 年 3 月。
[SHA-1]
FIPS PUB 180-1。 Secure Hash Standard. U.S. Department of Commerce / National Institute of Standards and Technology
[SOAP]
W3C 纪要,“ SOAP: Simple Object Access Protocol 1.1,”2000 年 3 月 8 日。
[SOAP-SEC]
W3C 纪要,“ SOAP Security Extensions: Digital Signature,”2001 年 2 月 6 日。
[URI]
T. Berners-Lee、R. Fielding 和 L. Masinter,“ Uniform Resource Identifiers (URI): Generic Syntax,”RFC 2396,MIT/LCS,美国加利福尼亚州尔湾,Xerox Corporation,1998 年 8 月。
[XML-C14N]
W3C 推荐,“ Canonical XML Version 1.0,”2001 年 3 月 15 日。
[XML-Encrypt]
W3C 工作草案,“ XML Encryption Syntax and Processing,”2002 年 3 月 04 日。
[XML-ns]
W3C 推荐,“ Namespaces in XML。”1999 年 1 月 14 日。
[XML-Schema1]
W3C 推荐,“ XML Schema Part 1: Structures,”2001 年 5 月 2 日。
[XML-Schema2]
W3C 推荐,“ XML Schema Part 2: Datatypes,”2001 年 5 月 2 日。
[XML Signature]
W3C 已提议推荐,“ XML Signature Syntax and Processing,”2001 年 8 月 20 日。
[WS-Routing]
H. Nielsen 和 S. Thatte,“ Web Services Routing Protocol,”Microsoft,2001 年 10 月。
[X509]
S. Santesson 等,“ Internet X.509 Public Key Infrastructure Qualified Certificates Profile。”
[XPath]
W3C 推荐,“ XML Path Language,”1999 年 11 月 16 日。
原创粉丝点击