利用WSE 加密SOAP报文(6)

** 加密对外发送的报文 ** ** **

我已经修改了前面的 ** GetXmlDocument ** 方法,让它可以使用由 WSE 实现的基于 X.509 非对称加密技术。加密回应报文, ** FindCertificateBySubjectString ** 方法可以用来接收客户端证书的公开备份,一个来自本地机器账号的个人储存室给的客户端证书。这个证书然后被用来创建一个新的 X.509 安全 Token ,这个 Token 将被加入到响应报文的 SoapContext 的安全 Token 集合里。另外,在对称加密例子中引用的命名空间,你应该再加一个 ** using ** 指示附来引用一个 ** Microsoft.WebServices.Security.X509 ** 命名空间。 ** GetXmlDocument ** 方法代码如下:

//创建一个用于返回的简单XML文档

XmlDocument myDoc = new XmlDocument();

myDoc.InnerXml =

"

1<encryptedresponse>This is sensitive data.</encryptedresponse>

";

"

1<encryptedresponse>这里是敏感数据.</encryptedresponse>

";

//得到响应报文的SoapContext

SoapContext myContext = HttpSoapContext.ResponseContext;

//打开并读取本地机器帐号的个人证书储存室

X509CertificateStore myStore =

X509CertificateStore.LocalMachineStore(

X509CertificateStore.MyStore);

myStore.OpenRead();

//查找所有名为”我的证书”的证书,然后将所有匹配的证书添加到证书集合中

X509CertificateCollection myCerts =

myStore.FindCertificateBySubjectString("My Certificate");

X509Certificate myCert = null;

//查找在集合中中的第一个证书

if (myCerts.Count > 0)

{

myCert = myCerts[0];

}

//确定我们有一个可以用于加密的证书

if (myCert == null || !myCert.SupportsDataEncryption)

{

throw new ApplicationException("Service is not able to

encrypt the response");

return null;

}

else

{

//使用有效的证书来创建一个安全 Token

X509SecurityToken myToken = new X509SecurityToken(myCert);

//WSE将使用这个标记来加密报文正文的

//WSE产生一个KeyInfo元素,用来请求客户端上曾用于给报文解密的证书

EncryptedData myEncData = new EncryptedData(myToken);

//将已加密数据元素添加到响应报文的SoapContext上

myContext.Security.Elements.Add(myEncData);

return myDoc;

}

基于前面的方法, WSE 管道产生了下面的有相应 Security 头、密文和密钥信息的元素:

 1<soap:envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 2<soap:header>
 3<wsu:timestamp xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
 4<wsu:created>2003-02-11T01:34:01Z</wsu:created>
 5<wsu:expires>2003-02-11T01:39:01Z</wsu:expires>
 6</wsu:timestamp>
 7<wsse:security soap:mustunderstand="1" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/07/secext">
 8<xenc:encryptedkey type="http://www.w3.org/2001/04/xmlenc#EncryptedKey" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
 9<xenc:encryptionmethod algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"></xenc:encryptionmethod>
10<keyinfo xmlns="http://www.w3.org/2000/09/xmldsig#">
11<wsse:securitytokenreference>
12<wsse:keyidentifier valuetype="wsse:X509v3">
13
14YmlKVwXYD8vuGuYliuIYdEAQQPw= 
15
16</wsse:keyidentifier>
17</wsse:securitytokenreference>
18</keyinfo>
19<xenc:cipherdata>
20<xenc:ciphervalue>UJ64Addf3Fd59XsaQ=…</xenc:ciphervalue>
21</xenc:cipherdata>
22<xenc:referencelist>
23<xenc:datareference uri="#EncryptedContent-608eef8b-4104-4469-95b6-7cb4703cfa03"></xenc:datareference>
24</xenc:referencelist>
25</xenc:encryptedkey>
26</wsse:security>
27</soap:header>
28<soap:body wsu:id="Id-70179c5b-4975-4932-9ecd-a58feb34b0d3" xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
29<xenc:encrypteddata id="EncryptedContent-608eef8b-4104-4469-95b6-7cb4703cfa03" type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
30<xenc:encryptionmethod algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"></xenc:encryptionmethod>
31<xenc:cipherdata>
32<xenc:ciphervalue>
33
344o1b4befwBJu6tzuaygfrAaX0UGtaYKcw2klIbuZPjLi...z8i2ypHN4+w== 
35
36</xenc:ciphervalue>
37</xenc:cipherdata>
38</xenc:encrypteddata>
39</soap:body>
40</soap:envelope>

注意在这个已加密的报文里面,由非对称加密过的 ** EncryptedKey ** 元素包含了用于给报文正文加密的对称加密密钥。 ** ReferenceList ** 元素引用了报文正文的 ** EncryptedData ** 元素的 Id 属性。虽然我在我的例子中没这样做,标记这个消息以便能让容器验证发送者其实是个不错的想法。关于使用 WSE 来标记报文的详细信息,看 WS-Security Authentication and Digital Signatures with Web Services Enhancements

Published At
Categories with Web编程
Tagged with
comments powered by Disqus