BinarySecurityToken
在WS-Security規範出現之前,針對Web Service或者其他的分佈式技術並不是沒有安全協議來保證它們的安全。只是這些協議一旦跨越了企業邊界往往會受到防火牆的影響,而不再起作用。在WS-Security中,並沒有拋棄這些現有的協議,而是將這些Binary的Security Token通過Encoding的方式集成到XML元素中,從而在Web Service中仍然能使用這些經典的安全協議,並利用SOAP消息穿越防火牆的特性,使它們適用於新的環境。這類Security Token在WS-Security中被稱爲BinarySecurityToken,目前僅支持X509v3 Certificate和Kerberos兩種,但是利用XML的高度擴展性,用戶可以定義自己的BinarySecurityToken。
下面是BinarySecurityToken的標準格式:
<wsse:BinarySecurityToken wsu:Id=...
EncodingType=...
ValueType=...>
...Binary Data ...
<wsse:BinarySecurityToken/>
其中EncodingType屬性指定將Binary數據Encoding到XML中的方法(常用Base64); ValueType屬性指定BinarySecurityToken的類型(比如X509v3); 元素內容則是經過Encoding的BinaryToken的內容。
X.509Token
使用X.509 Token來保證消息安全在介紹UsernameToken的文章最後已經提到。如果把UsernameToken從那個例子中去除,就變成了WSE中已經實現了的AnonymousForCertificate。
下圖就是AnonymousForCertificate對SOAP Envelop的擴展結構。
可以看出它和UsernameForCertificate非常相似,僅僅缺少了被加密的UsernameToken元素. 這點也正如它的名字所描述的一致,即使用這種方式的用戶對於Service來說是匿名的,也就沒有用戶鑑別的概念. 這恰好適用於那些僅僅需要保證消息安全而不需要驗證用戶身份的應用. 在介紹UsernameForCertificate的時候,並沒有詳細說明對X509Certificate Token的引用, 這裏做一些補充. 先來回顧一下之前在是如何引用X509Certificate Token. 從示意圖上我們也可以看出X509Certificate Token並沒有象UsernameToken那樣被包含在Request Security Head中, 爲什麼? 原因很簡單, 因爲這裏的X509證書並不是Client自己的證書,而是Service的證書(根據對稱密鑰的原理,加密需要使用消息接受方的公鑰). 以下是採用KeyIdentifier來引用Service的證書的方式.
<xenc:EncryptedKey wsu:id="userSysmetricKey">
…
<ds:KeyInfo>
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier
ValueType="...oasis-wss-soap-message-security-1.1#ThumbPrintSHA1">
LKiQ/CmFrJDJqCLFcjlhIsmZ/+0=
</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
…
</xenc:EncryptedKey>
對於這種使用消息接受方X509證書加密的應用場景, 在WS-Security1.1規範中還定義了另一種引用證書的方法---X509IssuerSerial.
<xenc:EncryptedKey wsu:id="userSysmetricKey">
…
<ds:KeyInfo>
<wsse:SecurityTokenReference>
<ds:X509Data>
<ds:X509IssuerSerial>
<ds:X509IssuerName>
DC=ACMECorp, DC=com
</ds:X509IssuerName>
<ds:X509SerialNumber>12345678</ds:X509SerialNumber>
</ds:X509IssuerSerial>
</ds:X509Data>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
….
</xenc:EncryptedKey>
使用AnonymousForCertificate的方法最大的缺陷就是無法實現用戶的身份鑑別, 然而在大多數的應用中這個功能是不可豁缺的. 使用UsernameForCertificate可以達到鑑別用戶身份的目的, 不過它一般用於保證個人用戶和企業之間的安全. 而企業與企業之間常採用X509證書來達到互相的信任.一方面因爲使用X509證書的安全性要高於Username&Password, 另一方面從現實的角度你不可能爲每個企業分配一個用戶名密碼. 於是就會在SOAP Head中出現兩個X509證書, 從而實現相互認證. 這也是WSE中MutualCertificate所要實現的功能.
在採用兩個X509證書來實現相互認證中, 比AnonymousForCertificate方式多出了用戶的X509證書. 而加入它的原因就是要利用用戶的私鑰來簽名消息, 從而讓Service通過證書來鑑別用戶的身份.下圖就是MutualCertificate11對SOAP Envelop的擴展結構。
從中可以看出變化比較小,僅僅多出了一個用戶X509 Certificate,並用它對原來的ds:Signature元素做了一次簽名. 對應這副圖的Soap Envelop如下:
<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2001/12/soap-envelope"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc"
xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
<SOAP-ENV:Header>
<wsse:Security
xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/secext">
<wsse:BinarySecurityToken
wsu:Id="userX509Cert"
ValueType="…#X509v3"
EncodingType="…#Base64Binary">
MIIEZzCCA9CgAwIBAgIQEmtJZc0…
</wsse:BinarySecurityToken>
<xenc:EncryptedKey wsu:id="userSysmetricKey">
<xenc:EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
<ds:KeyInfo>
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier
ValueType="...oasis-wss-soap-message-security-1.1#ThumbPrintSHA1">
LKiQ/CmFrJDJqCLFcjlhIsmZ/+0=
</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>G2wDCq24FsgBGerE...</xenc:CipherValue>
</xenc:CipherData>
<xenc:ReferenceList>
<xenc:DataReference URI="#DiscountResponse"/>
</xenc:ReferenceList>
</xenc:EncryptedKey>
<ds:Signature wsu:id="originSignature">
<ds:SignedInfo>
<ds:CanonicalizationMethod
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"/>
<ds:Reference URI="#DiscountedBookingForPartnersResponse">
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>JwFsd3eQc0iXlJm5PkLh7...</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>BSxlJbSiFdm5Plhk...</ds:SignatureValue>
<ds:KeyInfo>
<wsse:SecurityTokenReference>
<wsse:Reference URI="#userSysmetricKey"
ValueType="...oasis-wss-soap-message-security-1.1#EncryptedKey"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
<ds:Signature>
<ds:SignedInfo>
...
<ds:Reference URI="#originSignature">
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>FeGre4lWv1lY2Kn4LJkg9...</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>ADfkTeYsGen5Re4L...</ds:SignatureValue>
<ds:KeyInfo>
<wsse:SecurityTokenReference>
<wsse:Reference URI="#userX509Cert"
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body wsu:Id="DiscountedBookingForPartnersResponse">
<s:GetSpecialDiscountedBookingForPartnersResponse
xmlns:s="http://www.MyHotel.com/partnerservice ">
<xenc:EncryptedData
wsu:Id="DiscountResponse"
type="http://www.w3.org/2001/04/xmlenc#Element">
<xenc:EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc "/>
<CipherData>
<CipherValue>XD6sFa0DrWsHdehrHdhcW0x...</CipherValue>
</CipherData>
</xenc:EncryptedData>
</s:GetSpecialDiscountedBookingForPartnersResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
和加密引用證書一樣, 在WS-Security1.1中爲簽名也定義了3種引用方式.第一種就是上述的引用BinarySecurityToken. 第二種同加密所用的第二種方法一樣採用X509IssuerSerial.第三種是KeyIdentifier, 只不過與加密所用的KeyIdentifier的類型不同,下面是使用KeyIdentifier做簽名的引用的示例:
<ds:Signature
…
<ds:KeyInfo>
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier EncodingType="...#Base64Binary"
ValueType="...#X509SubjectKeyIdentifier">
MIGfMa0GCSq…
</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
同時使用Client和Service的X509證書, 可以在保證消息安全的同時實現Client與Service的身份鑑別. 與UsernameForCertificate用於個人與企業之間的安全不同的是MutualCertificate通常用於保障企業與企業之間的安全.
應用場景:
B2B供應鏈, 在物資需求方的企業內部使用Kerberos協議來保障個人或各個部門的安全, 而在物資需求方和供應方之間採用X509 Certification.
參考資料:
OASIS X509 Token Profile 1.1
Protect Your Web Services Through The Extensible Policy Framework In WSE 3.0