本文档中使用了下列名称空间:
前缀 |
名称空间 |
|
s |
http://www.w3.org/2001/12/soap-envelope |
soap根nm,定义soap中最基本Envelope、Header、Body、Fault等数据结构 |
ds |
http://www.w3.org/2000/09/xmldsig# |
xml签名根nm,定义xml签名的数据结构, 标准:[https://www.w3.org/TR/2002/REC-xmldsig-core-20020212/Overview.html ] |
xenc |
http://www.w3.org/2001/04/xmlenc# |
xml加密根nm, 标准:[https://www.w3.org/2008/xmlsec/Drafts/xmlenc-core-11/] |
m |
http://schemas.xmlsoap.org/rp |
从xsd文件来看,像是描述数据from和to的标准,版权属于微软 |
wsse |
http://schemas.xmlsoap.org/ws/2002/04/secext |
WS-Security的根nm(也是缩写) |
基于公私钥的数据加密技术,主要目的是防止数据传输过程中被冒充、被篡改、被非法截获
是站在数据发送方的角度,保护数据
用户调用服务器API,向服务器发送的一个可靠的验证信息,用于服务器判断是否为用户
所以技术的目的在于服务器认证请求发起者,减少传统web请求场景下网络上多次密码交互引入的风险
在soap的报文头中包含安全令性令牌,定义如下,令牌包含用户名节点和可选密码节点(wsse标准建议只有在使用安全的传输时才传送该元素)
疑问:为什么UsernameToken需要Id属性?
安全性令牌是服务端用来标记用户的技术,wsse标准并没有限制一个Username与Password的唯一对应关系,理论上是可以(甚至鼓励)实现一个Username对应多种Password方式的。因此Username某些情况下不足以唯一标记一个安全性令牌,因此需要增加Id属性,目的是唯一标记一个UsernameToken,另外从Id属性的类型xsd:ID也能反应设置这个属性的目的。
|
PassWord节点的Type属性可以有如下值
值 |
描述 |
wsse:PasswordText(缺省) |
用户名的实际密码。 |
wsse:PasswordDigest |
用户名密码摘要。值为 UTF8 编码的密码的 base64 编码的 SHA1 散列值。 |
示例:
...
...
... |
任何基于 XML 的安全性令牌都可以在
一个二进制安全性令牌有两个用于解释自身的属性。ValueType 属性表明安全性令牌是什么,比如说 Kerberos票据。EncodingType 表明安全性令牌如何被编码,例如使用 Base64Binary。
BinarySecurityToken 元素定义二进制编码的安全性令牌。编码过程用 EncodingType 属性指定,值类型和空间用 ValueType 属性指定。
注意:ValueType属性的类型xsd:QName表明类型定义在本xml作用域内
|
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)时使用。 |
EncodingType取值
QName |
描述 |
wsse:Base64Binary |
XML Schema base 64 编码 |
wsse:HexBinary |
XML Schema十六进制编码 |
示例:
MIIEZzCCA9CgAwIBAgIQEmtJZc0... |
注意:当在签名中使用
MIIEZzCCA9CgAwIBAgIQEmtJZc0... |
发送一组安全性令牌声明。有时候这些声明驻留在其它某些地方,需要接收的应用程序到指定的URL地址去获取。
|
示例:
|
注意:该元素还可以被用作
对于某些密钥类型(如 X.509 证书)来说,
然而,在本规范中,如果密钥类型在 wsse规范第 4.2 节中很好地定义过,那么使用
示例:使用该元素获取命名过的密钥的过程
|
消息发送方可能希望让消息接收方能够决定消息是否在传输过程中更改过,并验证消息是由特定安全性令牌持有人发送的。
当 XML 签名与
由于某些SOAP报头的不稳定性,发送者绝不能使用 XML 签名中定义的封装的签名转换。相对,消息应该显式包括要签署的必要元素。类似地,发送方绝不能使用 XML 签名中定义的封装签名。
本规范虑及多个签名附加在消息中的情况,这时每个签名都引用不同、甚至重叠的消息部分。这对于很多分布式应用程序都是很重要的,在这些应用程序程序中,消息要经过多个处理阶段。举例来说,发送方可能提交一个包含 orderID 报头的订单。发送方签署 orderID 报头和请求的主体(订单的内容)。当订单处理子系统收到这个时,它可能向报头插入一个 shippingID。发出订单的子系统然后会签署(最少)orderID 和 shippingID,可能还有请求主体。然后当运输部门处理和交付该订单后,可能会附加一个 shippedInfo 报头。运输部门将签署(最少)shippedInfo 和 shippingID,可能还有请求主体,然后将消息转发给记帐部门进行处理。记帐部门可以验证签名并决定订单的有效信任链,以及各个角色所做的事情。
所有依从的实现都必须能够处理
WS-Security 规范建立在 XML 签名的基础之上,因此具有与 XML 签名规范中指定的相同的算法需求。
下面的表描述了 WS-Security 推荐的其它算法:
算法类型 |
算法 |
算法 URI |
规范化 |
专用 XML 规范化,在签名hash前用于去除空格和其他格式 |
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)。
SOAP应用程序必须满足下面的条件:
如 XML 签名规范中所示, XPath过滤可以用于指定将签署的对象。然而,因为 SOAP消息交换模型允许中介体应用程序修改信封(如添加或删除报头块), XPath过滤在消息传递之后并不总能得到相同对象。使用 XPath过滤时应该注意避免因为这种修改导致后来的验证失败。
中介体应用程序修改的问题不仅仅在 XPath 处理中才会发生。由于规范化和 分类的原因,数字签名是这种关系的特别脆弱的例子。如果消息处理整体要保持健壮,中介体必须注意转换不会出现在数字签名组件的范围中。
鉴于和名称空间有关的安全性注意事项,本规范强烈推荐您使用提供相同或更多保护的“ 专用 XML 规范化(Exclusive XML Canonicalization)”算法或其它标准化算法。
如果发生下列情况,
如果签名验证失败,那么应用程序可能会使用 第 6 节中定义的错误代码向发送者报告失败情况。
下面的样本消息举例说明了完整性和安全性令牌的使用(一条完整的符合wsse标准的soap报文)。对于本示例,我们使用了假定的“RoutingTransform”,它选择不变的路由报头以及消息主体。
MIIEZzCCA9CgAwIBAgIQEmtJZc0rqrKh5i...
BL8jdfToEb1l/vXcMZNNjPOV...
QQQ
|
本规范允许通过发送方和接收方共享的通用对称密钥或消息中带有的加密形式的密钥,对消息主体块、报头块、任意这些子结构和附件的组合进行加密。简单说就是不对整个xml加密,支队部分敏感信息加密。
为了实现这种灵活性,我们利用了 XML 加密(XML Encryption)标准。我们将特别描述如何在
在加密 SOAP消息内的元素或元素内容时,您可以使用 XML 加密的
尽管在 XML 加密中,
|
当加密步骤涉及到使用密钥(它接着会被接收方的密钥加密并嵌入到消息中)加密 SOAP信封中的元素或元素内容时,就可以使用
这种构建方法在通过随机生成的对称密钥(该密钥接着由接收方的公共密钥加密)完成加密时很有用。下面举例说明了这个元素的使用:
|
在某些情况下,有关安全性的信息是以完全加密的形式提供的,或者加密时非 XML 附件会被加密。 XML 加密的
下面举例说明了使用该元素表明加密附件的方法:
|
使用上述其中一种子元素对 SOAP消息加密的部分或附件必须符合 XML 加密规范。加密的 SOAP消息必须还是一个有效的 SOAP信封。消息的创建者绝不能加密
当要加密 SOAP信封中的元素或元素内容(例如
注:签名和加密的顺序,一般是先签名后加密,签名验证要求对解密后原文,这样可以保证接收者既知道怎么解密又防止信息篡改
加密
创建符合此规范的加密 SOAP消息的一般步骤(非标准化的)如下所示(请注意,我们推荐使用
解密
当收到带有加密报头条目的 SOAP信封时,对于每个加密报头来说都应该进行下面的一般步骤(非标准的):
(001) (002) (003) (004) (005) (006) (007) (008) (009) (010) (011) (012) MIIEZzCCA9CgAwIBAgIQEmtJZc0rqrKh5i... (013) (014) (015) (016) (017) (018) (019) (020) (021) d2FpbmdvbGRfE0lm4byV0... (022) (023) (024) (025) (026) (027) (028) (029) (030) (031) (032) (033) (034) (035) (036) (037) (038) (039) LyLsF094hPi4wPU... (040) (041) (042) (043) (044) Hp1ZkmFZ/2kQLXDJbchm5gK... (045) (046) (047) (048) (049) (050) (051) (052) (053) (054) (055) (056) (057) (058) (059) d2FpbmdvbGRfE0lm4byV0... (060) (061) (062) (063) (064) |
让我们来回顾本示例中一些关密钥的部分:
在很多情况下,处理安全性信息时都会出现 错误。例如:
这些错误可以分为两 类:不支持的和失败的。
对于不支持的错误情况来说,接收者可以提供响应,告知发送者支持的格式等等。
对于失败的错误来说,接收者可以选择不响应,因为这可以算是拒绝服务(Denial of Service,DOS)或加密攻击的一种形式。
结合签名和加密失败来减少某些类型的攻击。
如果失败返回到发送者,那么必须使用 SOAP的“错误(Fault)”机制来报告错误。
下面的表描述了预定义的安全性错误代码。
错误的“不支持”类为:
出现的错误 |
错误代码 |
提供了不支持的令牌 |
wsse:UnsupportedSecurityToken |
使用了不支持的签名或加密算法 |
wsse:UnsupportedAlgorithm |
错误的“失败”类为:
出现的错误 |
错误代码 |
处理 |
wsse:InvalidSecurity |
提供了无效的安全性令牌 |
wsse:InvalidSecurityToken |
安全性令牌无法被验证或授权 |
wsse:FailedAuthentication |
签名或解密是无效的 |
wsse:FailedCheck |
引用的安全性令牌无法检索 |
wsse:SecurityTokenUnavailable |
参考资料:
[1] w3c-xml schema
[2] "RELAX NG"--Eric van der Vlist
[3] ws-secure中翻译
[4] xml-signature