简介
XML 已经成为一种用于在因特网上交换数据的有价值机制。SOAP,这种发送 XML 消息的方式,促使进程以一种前所未有的方式相互通信,而 UDDI 看起来正在快速成为整合 Web 服务的供应商和用户的标准;服务本身是 XML 以 WSDL (即“Web 服务描述语言”)形式描述的。如果没有 XML,将不可能有这种灵活性和能力,并且,正如许多人所说的,将有必要发明元语言。
安全性领域是另一个快速增长的领域。在不同团体之间建立信任的传统方法在公共因特网上已不合适,实际上,在大型 LAN 和 WAN 上也不合适。在这些情况下,基于非对称密码术的信任机制可能会非常有用,但实际上,部署和密钥管理的方便性、互操作性的范围和提供的安全性远不如各种的“公钥基础设施”(Public Key Infrastructures (PKI))的热情的供应商曾让我们相信的那样。处理层次数据结构,以及带有机密、访问权限或完整性等不同需求的数据的子集特别困难。另外,具有不同于 XML 文档的现今标准安全性控制的应用程序一点都不简单。
目前,一些团体正积极投身于检查这些问题和开发标准的活动中。其中主要的相关开发是 XML 加密和相关的 XML 签名、“可扩展访问控制语言(XACL)”和相关的“安全性断言标记语言(SAML — 以前是互为竞争对手的 AuthML 和 S2ML 的结合)”。所有这些都由 OASIS 和“XML 密钥管理规范(XKMS)”驱动。本文将 介绍 XML 加密和 XML 签名。
“XML 安全性套件”
部分原因是由于这些标准仍处于发展阶段,因此,开发人员可用的工具集和库的数量仍然有限,但十分确信的一点是,这正在开始发生变化。IBM 已经向“Java 社区过程(JCP)”提交了两种相关的“Java 规范请求(JSR)”。它们是 JSR-105、“XML 数字签名 API”和 JSR-106、“数字加密 API”。
“IBM 东京研究实验室”在 1999 年开发了“XML 安全性套件”作为 XML 签名的原型实现。它包含一些自动生成 XML 数字签名、实现 W3C 的“规范”XML 工作草案,以及通过 XML 加密的实验性实现来提供元素级加密的实用程序。它还提供一种在应用到 XML 文档时处理安全性特定要求的方式。还引入了“可扩展访问控制语言(XACL)”的 XML 模式定义。
developerWorks 有一篇 Doug Tidwell 著的文章详细讲述了该套件,可在 alphaWorks 站点获得该套件的最新版本。(请参阅参考资料。)
XML 加密和 XML 签名
象其它任何文档一样,可以将 XML 文档整篇加密,然后安全地发送给一个或多个接收方。例如,这是 SSL 或 TLS 的常见功能,但是更令人感兴趣的是如何对同一文档的不同部分进行不同处理的情况。XML 的一个有价值的好处是可以将一整篇 XML作为一个操作发送,然后在本地保存,从而减少了网络通信量。但是,这就带来了一个问题:如何控制对不同元素组的授权查看。商家可能需要知道客户的名称和地址,但是,无需知道任何正在使用的信用卡的各种详细信息,就像银行不需要知道购买货物的详细信息一样。可能需要防止研究人员看到有关个人医疗记录的详细信息,而管理人员可能正好需要那些详细信息,但是应该防止他们查看医疗历史;而医生或护士可能需要医疗详细信息和一些(但不是全部)个人资料。
密码术现在所做的远远不止隐藏信息。消息摘要确定文本完整性,数字签名支持发送方认证,相关的机制用于确保任何一方日后无法拒绝有效事务。这些都是远程交易必不可少的元素,现在,用于处理整个文档的机制开发得相当好。
有了一般的加密,对 XML 文档整体进行数字化签名不是问题。然而,当需要对文档的不同部分(可能由不同的人)签名,以及需要与选择性的方法一起来这样做时,就会出现困难。也许不可能或者不值得强制不同部分的加密工作由特定人员按特定顺序进行,然而成功地处理文档的不同部分将取决于是否知道这点。此外,由于数字签名断言已经使用了特定专用密钥来认证,所以要小心签名人是以纯文本形式查看文档项的,这可能意味着对由于其它原因而加密的部分内容进行了解密。在另一种情况下,作为更大集合中的一部分,可能对已经加密过的数据进行进一步加密。在牵涉单一 XML 文档(可能由一些不同的应用程序和不同的用户处理在工作流序列中使用的 Web 表单或一系列数据)的事务集中考虑的不同可能性越多,就越可能看到巨大的潜在复杂性。
还有其它问题。XML 语言的强项之一是,搜索是明确的,无二义性的:DTD 或 Schema 提供了相关语法的信息。如果将包括标记在内的文档的一部分作为整体加密,就会丧失搜索与那些标记相关的数据的能力。此外,如果标记本身被加密,那么一旦泄漏,它们将被利用对采用的密码术进行纯文本攻击。
这些是工作组正在考虑的一些方面。
XML 加密示例
XML 加密语法的核心元素是 EncryptedData 元素,该元素与 EncryptedKey 元素一起用来将加密密钥从发起方传送到已知的接收方,EncryptedData 是从 EncryptedType 抽象类型派生的。要加密的数据可以是任意数据、XML 文档、XML 元素或 XML 元素内容;加密数据的结果是一个包含或引用密码数据的 XML 加密元素。当加密元素或元素内容时,EncryptedData 元素替换 XML 文档加密版本中的该元素或内容。当加密的是任意数据时,EncryptedData 元素可能成为新 XML 文档的根,或者可能成为一个子代元素。当加密整个 XML 文档时,EncryptedData 元素可能成为新文档的根。此外,EncryptedData 不能是另一个 EncryptedData 元素的父代或子代元素,但是实际加密的数据可以是包括现有 EncryptedData 或 EncryptedKey 元素的任何内容。
加密工作草案给出了一些示例来演示:加密的颗粒度如何根据要求的不同而不同,以及可能出现什么结果。清单 1 中的代码片断显示了带有信用卡和其它个人信息的未加密 XML 文档。在某些情况下(例如,隐藏支付机制的信息),可能希望加密除客户名称以外的所有信息,清单 2 的代码片断演示了如何这样做。
清单 1. 显示 John Smith 的银行帐户、5000 美元限额、卡号和有效期的的信息
<PaymentInfo xmlns='http://example.org/paymentv2'> <Name>John Smith<Name/> <CreditCard Limit='5,000' Currency='USD'> <Number>4019 2445 0277 5567</Number> <Issuer>Bank of the Internet</Issuer> <Expiration>04/02</Expiration> </CreditCard> </PaymentInfo>
清单 2. 除名称之外全部被加密的加密文档
<PaymentInfo xmlns='http://example.org/paymentv2'> <Name>John Smith<Name/> <EncryptedData Type='http://www.w3.org/2001/04/xmlenc#Element' xmlns='http://www.w3.org/2001/04/xmlenc#'> <CipherData><Ciphervalue>A23B45C56</Ciphervalue></CipherData> </EncryptedData> </PaymentInfo>
但是,在其它情况下,可能只需要隐藏一些敏感内容 — 可能来自商家或其它第三方 — 清单 3 演示了这点。(请注意,显示了与加密内容相关的标记名。)
清单 3. 只隐藏了信用卡号的加密文档
<PaymentInfo xmlns='http://example.org/paymentv2'> <Name>John Smith<Name/> <CreditCard Limit='5,000' Currency='USD'> <Number> <EncryptedData xmlns='http://www.w3.org/2001/04/xmlenc#' Type='http://www.w3.org/2001/04/xmlenc#Content'> <CipherData><Ciphervalue>A23B45C56</Ciphervalue> </CipherData> </EncryptedData> </Number> <Issuer>Bank of the Internet</Issuer> <Expiration>04/02</Expiration> </CreditCard> </PaymentInfo>
可能还有必要加密文档中的所有信息,清单 4 演示了这点。
清单 4. 隐藏了全部内容的加密文档
<EncryptedData xmlns='http://www.w3.org/2001/04/xmlenc#' Type='http://www.isi.edu/in-notes/iana/assignments/media-types/text/xml'> <CipherData><Ciphervalue>A23B45C56</Ciphervalue></CipherData> </EncryptedData>
CipherData 可以封装,也可以引用原始加密数据。在第一种情况下,Ciphervalue 元素的内容显示原始数据,而在第二种情况,使用 CipherReference 元素,这包括了一个指向加密数据位置的 URI。
规范的 XML
对应用了密码散列算法的消息进行最轻微的更改也会产生不同的值。这为消息完整性方面提供了信任,并适于通常用法,但是也引入了进一步的复杂性 — 两个 XML 文档虽然在逻辑上相等,但可能在确切文本比较中不同。象行定界符、空标记、在属性中使用十六进制而不是名称以及在特定情况下存在注释或注释变体这样的事情都可以成为文档的逻辑结构不受影响而实际彼此不同的实例。规范的 XML 规范描述了一种生成文档的物理表示(也成为范式)的方法,该范式解释允许的变体,以便如果两个文档具有同一范式,则认为两个文档在给定应用程序上下文中是逻辑相等的。
对于加密、特别是数字签名来说,这尤为重要,因为很明显,逻辑上相同的文本变体不应该表示文档的完整性及其发送方的认证是可疑的。用不同工具(譬如,解析器)生成不同文本(并因而生成不同消息摘要)进行处理时也可能发生这样的事。因此,在生成签名和验证计算期间,应该在范式上进行消息摘要。如果摘要匹配,这将确定:即使文本形式可能不同,它们在其上计算的范式也匹配。
XML 签名示例
可以将 XML 签名应用到任意数据内容。那些应用到相同 XML 文档中数据的签名称为封装或被封装的签名,而那些数据在签名元素外部的签名称为 分离签名。清单 5 取自签名候选推荐文档,它是一个简单分离签名的实例。
清单 5. 一个简单分离签名的示例
[s01] <Signature Id="MyFirstSignature" xmlns="http://www.w3.org/2000/09/xmldsig#"> [s02] <SignedInfo> [s03] <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/ REC-xml-c14n-20010315"/> [s04] <SignatureMethod Algorithm="http://www.w3.org/2000/09/ xmldsig#dsa-sha1"/> [s05] <Reference URI="http://www.w3.org/TR/2000/REC-xhtml1-20000126/"> [s06] <Transforms> [s07] <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n- 20010315"/> [s08] </Transforms> [s09] <DigestMethod Algorithm="http://www.w3.org/2000/09/ xmldsig#sha1"/> [s10] <Digestvalue>j6lwx3rvEPO0vKtMup4NbeVu8nk=</Digestvalue> [s11] </Reference> [s12] </SignedInfo> [s13] <Signaturevalue>MC0CFFrVLtRlk=</Signaturevalue> [s14] <KeyInfo> [s15a] <Keyvalue> [s15b] <DSAKeyvalue> [s15c] <p></p><Q></Q><G></G><Y></Y> [s15d] </DSAKeyvalue> [s15e] </Keyvalue> [s16] </KeyInfo> [s17] </Signature>
实际签名的信息是位于 s02 行和 s12 行之间,即 SignedInfo 元素。在签名的部分中包含用于计算 Signaturevalue 元素的算法的引用,而那个元素本身位于签名部分之外(在 s13 行上)。s04 行上的 SignatureMethod 引用的是将规范的 SignedInfo 转换成 Signaturevalue 所用的算法。它是密钥相关的算法和摘要算法(在这里是 DSA 和 SHA-1)的组合,可能还具有象填充这样的操作。KeyInfo 元素(在这里位于 s14 行和 s16 行之间 — 该元素是可选的)指出用来验证签名的密钥。
转换
正如前面所提到的,加密、签名、修改和可能进行的更多签名所发生的顺序有很多种可能性。用户可能需要向已经部分加密或部分签名的表单字段中输入更多数据,并且需要能够在不妨碍以后的验证和解密的前提下这样做。为解决这种情况,W3C 最近发布了一个有关 XML 签名的解密转换工作草案。(请参阅参考资料。)
下面这个示例摘自那个文档,它演示了如何建议文档接收方采用正确的解密和签名验证顺序。第一个代码段显示了要签名的文档部分 — order 元素;其中,第 7 行到第 11 行的 cardinfo 元素是关于个人和财务方面的详细信息,它是纯文本,但也存在一些加密数据(第 12 行)。
清单 6. XML 文档中的 order 元素
[01] <order Id="order"> [02] <item> [03] <title>XML and Java</title> [04] <price>100.0</price> [05] <quantity>1</quantity> [06] </item> [07] <cardinfo> [08] <name>Your Name</name> [09] <expiration>04/2002</expiration> [10] <number>5283 8304 6232 0010</number> [11] </cardinfo> [12] <EncryptedData Id="enc1"xmlns="http://www.w3.org/ 2001/04/xmlenc#"></EncryptedData> [13] </order>
清单 7. 经过签名和进一步加密、且现在显示转换信息的 order 文档
[01] <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> [02] <SignedInfo> [03] [04] <Reference URI="#order"> [05] <Transforms> [06] <Transform Algorithm="http://www.w3.org/2001/04/ xmlenc#decryption"> [07] <DataReference URI="#enc1" xmlns="http://www.w3.org/2001/04/xmlenc#"/> [08] </Transform> [09] <Transform Algorithm="http://www.w3.org/TR/2000/ CR-xml-c14n-20001026"/> [10] </Transforms> [11] [12] </Reference> [13] </SignedInfo> [14] <Signaturevalue></Signaturevalue> [15] <Object> [16] <order Id="order"> [17] <item> [18] <title>XML and Java</title> [19] <price>100.0</price> [20] <quantity>1</quantity> [21] </item> [22] <EncryptedData Id="enc2" xmlns="http://www.w3.org/2001/04/xmlenc#"></EncryptedData> [23] <EncryptedData Id="enc1" xmlns="http://www.w3.org/2001/04/xmlenc#"></EncryptedData> [24] </order> [25] </Object> [26] </Signature>
第 1 行到 第 26 行的 Signature 元素现在包含前面的 order 元素(位于第 16 行到第 24 行),和以前的加密纯文本 cardinfo(显示在第 22 行这一行中)。有两个转换引用:解密(第 6 行到第 8 行)和规范化(第 9 行)。解密转换指示签名验证器解密除 DataRef 元素中第 7 行指定的数据之外的所有加密数据。解密了第 22 行中的 EncryptedData 元素之后,规范化 order 元素并且恰当地验证签名。
其它相关语言和规范
隐藏 XML 文档中的敏感信息、建立完整性以及认证这些文档的不同部分的来源主要通过遵循加密和签名规范中列出的步骤来处理的,在引用的 W3C 草案中描述该规范(请参阅参考资料)。另外,还有其它紧密相关的领域,例如认证用户或系统、标识授权级别和管理密钥,所有这些都与 XML 安全性相关。
SAML 是一个由 OASIS 驱动的模型,它尝试融合相互竞争的 AuthML 和 S2ML 规范,使认证和授权信息的互换便于进行。“可扩展访问控制标记语言”是与 SAML 紧密相关的,但它更着重于特定 XML 文档的上下文中的面向主题特权对象的安全性模型,它也由 OASIS 指导,又是被称为 XACML 或 XACL(即使在同一些文档中)。通过用 XACL 编写规则,策略制订者可以定义,对于特定 XML 文档和前面所述的情况中的相关事情,由谁来实施哪些访问特权。
关于SAML的详细内容,我将在下一篇Blog内讲述.
Atas ialah kandungan terperinci XML加密和XML签名简介的具体介绍. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!