赞
踩
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?
随着客户应用程序用例的逐步发展,确定了一套有关安全性的非功能性需求:
客户与其业务伙伴之间的通信在因特网上传播时不应该被第三方看到。
客户必须能够确定消息来自哪个人并能够证实发送方就是那个发送方声称的发送方。
客户必须能够确定被传送的数据没有被篡改。
使用 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+eBjx5D2QMyr8ocZIZWNYHGf9zYhB4XWILPCTvhNV7dIe3l8ARepOA1ABFK2OMy
pzb+Rb+nWQeo//yFz/28PmL63kdLiE72qmmQuzuPa5NXaV9pJ4JKw86QdLhGGpFIRH
18Iugf3xLFwQEZqKYnblTUs7ftnTgW5r4HH492k=</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>
MIIB0TCCAToCAQAwDQYJKoZIhvcNAQEEBQAwTzELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE9rbGFo
b21hMRAwDgYDVQQHEwdVbmsam3duMQwwCgYDVQQKEwNJQk0xDTALBgNVBAsTBEphdmEwHhcNMDIw
OTI1MTAxMTQ4WhcNMDMwOTI1MTAxMTQ4WjATMREwDwYDVQQDEwhKb2huIERvZTCBnzANBgkqhkiG
9w0BAQEFAAOBjQAwgYkCgYEA2sW+eBjx5D2QMyr8ocZIZWNYHGf9zYhB4XWILPCTvhNV7dIe3l8A
RepOA1ABFK2OMypzb+Rb+nWQeo//yFz/28PmL63kdLiE72qmmQuzuPa5NXaV9pJ4JKw86QdLhGGp
FIRH18Iugf3xLFwQEZqKYnblTUs7ftnTgW5r4HH492kCAwEAATANBgkqhkiG9w0BAQQFAAOBgQCs
OD02WMoYcMR7Sqdb9oQyk7Nn4rQ5DBgZ5mxGGVzWxBZW/QON+Ir2j4KUjX1jalMvbHa9lnhPQmJi
Ued923rza7fvdRG2CDalbW0R3aPd5q0u3akP0/Ejb7z5o88heajCSgfRruvU+ZdOTT3Oe+RBQgw8
VuzbLApPnXiehowYuA==
</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 服务开发工具添加了这种支持时,它只会变得更好。
参考资料
请查看 W3C Web 站点的 W3C Exclusive XML Canonicalization Version 1.0 规范。
请查看 W3C Web 站点的 W3C XML Signature Syntax and Processing 推荐规范。
请查看 W3C Web 站点的 RFC 2437 (PKCS1)。
请阅读美国商业部/国家标准与技术研究院的安全散列标准。
请浏览 RSA 实验室有关当今加密术的常见问题解答,版本 4.1(2000 年)。
请查看更多有关 IBM jStart 计划的相关信息。
您可以在 developerWorks Web 服务专区查看 WS-Security 规范 V1.0 草案(2002 年 4 月 5 日)。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。