0

我正在尝试实现一个 java webservice 客户端。Soap 消息已签名(内部分离签名)。

我有一个验证为正确签名的有效消息示例。

当我尝试我的代码时,消息未正确签名。试图跟踪问题,我意识到问题(或我的错误)与 .

在正常工作的示例中,我可以“验证” DigestValue 的创建方式:

<ds:Reference URI="#Id-4889213">
<ds:Transforms>
  <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
    <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList=""/>
  </ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>VYRVoWOIiZx/7QMavLyDmAZ3Mb0=</ds:DigestValue>

引用 URI 是消息正文:

<soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Id-4889213">
<web:consultarEstados xmlns:web="https://webservice.face.gob.es"/>

如果我手动“规范化”这个,并尝试使用 apli sha1,我得到的结果正是 DigestValue。

手工规范化的soapenv:Body:

<soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Id-4889213"><web:consultarEstados xmlns:web="https://webservice.face.gob.es"></web:consultarEstados></soapenv:Body>

生成sh1值的命令:(用can.body存储在bodyib.txt previos字符串中)

cat bodyib.txt|openssl dgst -binary -sha1 | openssl enc -base64

输出:

VYRVoWOIiZx/7QMavLyDmAZ3Mb0= (Yes, the value in DigestValue !!)

当我签署我的消息时,我得到以下参考:

<ds:Reference URI="#Id-4889213">
<ds:Transforms>
    <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
    <InclusiveNamespaces xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList=""/>
    </ds:Transform>
    </ds:Transforms>
    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
    <ds:DigestValue>sA5MIQPm4b2YhMRTPHg9CY8J1FI=</ds:DigestValue>
</ds:Reference>

我模仿所有名称空间和 Id 以获得与我的示例完全相同的肥皂消息。所以我得到了愚蠢的soapenv:Body:

<soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Id-4889213">

如果我手动对其进行规范化,我会得到与之前完全相同的字符串,但参考中显示的 DigestValue 不一样。

我已经尝试过使用两个不同的 jsr105 提供程序:

甲骨文:“org.jcp.xml.dsig.internal.dom.XMLDSigRI” Apcher santuario(1.5.6):“org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI”

结果是相同的摘要(与我根据我的示例所期望的不同)。我不知道这些摘要是从哪里来的。当我尝试手动计算时,结果就是示例中的结果。

我想我对这一切没有一些概念,因为使用两个不同的库我得到了相同的值,所以我不认为问题是这个库的代码。

4

1 回答 1

2

我发现要签名的数据有什么不同。该问题与http://www.w3.org/2001/10/xml-exc-c14n#变换算法有关。我不知道女巫一个是否正确:

我的示例中正在签名的内容:

<soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Id-4889213"><web:consultarEstados></web:consultarEstados></soapenv:Body>

我不知道为什么

<web:consultarEstados></web:consultarEstados> 

没有命名空间信息。

这可能是http://www.w3.org/2001/10/xml-exc-c14n#的 org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI 实现中的错误,可能是元素为空时.

我会试着找出答案。

终于发现问题:在签名之前我正在做一些命名空间的改变,试着用我的例子来做。我必须添加: soapEnvelope.getOwnerDocument().normalizeDocument();

为了规范化正常工作。没有这个,规范化就无法正常工作。

于 2014-05-05T13:19:32.757 回答