对SOAP报文进行数字签名

时间:2024-03-14 19:11:18

16.7.3  对SOAP报文进行数字签名
使用用户名/密码虽然可以验证SOAP请求报文发送者的身份实现授权访问,但是服务端却无法保证报文在传输过程中没有被篡改——黑客可以截取使用了UsernameToken的SOAP报文并在篡改后再发送给服务端,就会使SOAP报文的完整性遭受破坏。
此外,仅使用UsernameToken的SOAP,客户端用户可以抵赖自己的操作行为,因为黑客确实可以通过一些手段(如键盘监听、暴力**等)获取用户的密码。
而 数字签名则可以解决以上的问题,保证交易的完整性和不可抵赖性。客户端通过私钥对SOAP报文进行数字签名,由于私钥只为个人拥有,因此不可抵赖性得到了 保证。数字签名其实是使用私钥对报文的摘要进行加密,只有报文在传输过程中不被篡改,接收端在进行数字签名验证时才可能成功,因此完整性又得到了保证。
下面,我们在客户端对请求SOAP进行数字签名,而服务端验证客户端签名的合法性。客户端使用client私钥进行数字签名,服务端使用client的数字证书(包含client的公钥)验证客户端的签名。
服务端
服务端在验证客户端的签名时,必须访问serverStore.jks中的client数字证书,所以需要进行相应的配置,如代码清单16-14所示:

对SOAP报文进行数字签名

insecurity_sign.properties定义了serverStore.jks的位置 以及访问密码,WSS4J使用org.apache.ws.security.components.crypto.Merlin类作为 SecurityProvider。insecurity_sign.properties的内容如下所示:

对SOAP报文进行数字签名

客户端
客户端必须通过注册OutHandler使用私钥对SOAP报文进行数字签名。客户端的私钥别名为client,存储在clientStore.jks的**库中。访问**库和私钥都必须提供密码,因此必须进行相应的设置。

对SOAP报文进行数字签名
对SOAP报文进行数字签名

和用户名/密码进行身份认证相似,在进行数字签名时,也需要提供用户名和密码,不过两者的用途是不一 样的,后者的用户名为**库中**对的别名,密码为私钥的访问**。③处的client为clientStore.jks**库中客户端**对的别名,私 钥访问密码通过PasswordHandler获取,如代码清单16-16所示:

对SOAP报文进行数字签名

客户端的私钥位于clientStore.jks中,访问clientStore.jks的配置信息通过outsecurity_ sign.properties属性文件进行描述:

对SOAP报文进行数字签名

运行BbtForumServiceSignClient后,查看SOAP请求报文,用户将看到报文 头拥有一个<ds:Signature>元素,包含了签名信 息<ds:SignedInfo>、<ds:SignatureValue>、<ds:KeyInfo>等元素,它 们分别代表签名信息、签名值以及签名所用**的信息:

<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/
">
<SOAP:Header>
<wsse:Security>
<ds:Signature>
<ds:SignedInfo>…<ds:SignedInfo>
<ds:SignatureValue>…</ ds:SignatureValue>
<ds:KeyInfo>…</ds:KeyInfo >
</ds:Signature>
</wsse:Security>
</SOAP:Header>
<SOAP:Body Id='Body'>
…
</SOAP:Body>
</SOAP:Envelope>