由于 XML 属性顺序更改而导致数字签名损坏

我正在用 Java 开发一个 SOAP Web 服务器,其中我的响应必须带有时间戳和签名。要签名的节点是 BODY 和 TIMESTAMP。


问题在于,XmlSignature.sign方法对这些节点进行解组,将命名空间属性放置在 BODY 和 TIMESTAMP 标记中的 Id 属性之前,而由 JAX-WS 解组的出站响应字符串将命名空间属性放置在Id之后。


因此,这些节点计算出的摘要值对记录器无效,即:


Actual Digest: ljf4iIFTgpHUDKtLjYJEto9Ro5k=


Expected Digest: iIYWShXDG4o8f/9L08d+apVsGx0=

我认为如果我可以指定解组器的属性顺序(在签名或响应消息中),我也可以使顺序匹配,但我还没有做到这一点。


我测试了 SOAPHandler 来拦截响应,但我发现无法更改消息属性顺序。


这是由签名类生成的节点时间戳的 XML 代码:


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

                <wsu:Created>2019-09-19T10:00:00.000Z</wsu:Created>

                <wsu:Expires>2019-09-19T10:05:00.000Z</wsu:Expires>

            </wsu:Timestamp>

这是响应中发送的 TIMESTAMP 节点的 XML 代码:


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

                <wsu:Created>2019-09-19T10:00:00.000Z</wsu:Created>

                <wsu:Expires>2019-09-19T10:05:00.000Z</wsu:Expires>

            </wsu:Timestamp>

BODY 节点也是如此。签名:


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

            <AsignacionNotarioResponse xmlns="http://ancert.notariado.org/XML">

                <CodigoRespuesta>0</CodigoRespuesta>

                <IdNotificacionCGN>371003</IdNotificacionCGN>

            </AsignacionNotarioResponse>

        </S:Body>

发送:


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

            <AsignacionNotarioResponse xmlns="http://ancert.notariado.org/XML">

                <CodigoRespuesta>0</CodigoRespuesta>

                <IdNotificacionCGN>371003</IdNotificacionCGN>

            </AsignacionNotarioResponse>

        </S:Body>


PIPIONE
浏览 83回答 1
1回答

胡说叔叔

经过几天的努力,我终于找到了问题所在。为了对正文进行签名,我必须为标签分配一个 ID,以及在 tar 下对此 ID 的引用。所以我的 XML 看起来像这样:...之后,我用我的私钥签署了传出消息。这是我将 Id 属性添加到 Body 标记的函数:/**&nbsp;* Asigna un identificador único al nodo Body del mensaje.&nbsp;*&nbsp;&nbsp;* @param soapMessage&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Mensaje SOAP&nbsp;*&nbsp;&nbsp;* @throws SOAPException&nbsp;*/private static void asignarIdNodoBody(SOAPMessage soapMessage) throws SOAPException {&nbsp; &nbsp; String idBody = "Body-123456";&nbsp; &nbsp; SOAPBody soapBody = soapMessage.getSOAPBody();&nbsp; &nbsp; soapBody.setAttributeNS(NAMESPACE_WSU, "wsu:Id", id_body);}由于某种我不明白的奇怪原因,上面的代码导致添加的数字签名没有通过验证。我用这个函数替换了上面的函数:/**&nbsp;* Asigna un identificador único al nodo Body del mensaje.&nbsp;*&nbsp;&nbsp;* @param soapMessage&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Mensaje SOAP&nbsp;*&nbsp;&nbsp;* @throws SOAPException&nbsp;*/private static void asignarIdNodoBody(SOAPMessage soapMessage) throws SOAPException {&nbsp; &nbsp; String idBody = "Body-123456";&nbsp; &nbsp; SOAPBody soapBody = soapMessage.getSOAPBody();&nbsp; &nbsp; SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart().getEnvelope();&nbsp; &nbsp; Name name = soapEnvelope.createName("Id", "wsu", NAMESPACE_WSU);&nbsp; &nbsp; soapBody.addAttribute(name, id_body);}瞧!我之后添加了数字签名,现在它通过了验证。Referencia [0]&nbsp;&nbsp; &nbsp; URI:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; #Body-123456&nbsp; &nbsp; Validacion OK:&nbsp; &nbsp; true&nbsp;&nbsp; &nbsp; Digest:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;JMdmg+d/yJJA1wg7yzDctIBE9z4=&nbsp;&nbsp; &nbsp; Expected digest:&nbsp; JMdmg+d/yJJA1wg7yzDctIBE9z4=&nbsp;Referencia [1]&nbsp;&nbsp; &nbsp; URI:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; #TS-1000&nbsp;&nbsp; &nbsp; Validacion OK:&nbsp; &nbsp; true&nbsp;&nbsp; &nbsp; Digest:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sEY89etI7c+uGrFPh7W59nu/4ac=&nbsp;&nbsp; &nbsp; Expected digest:&nbsp; sEY89etI7c+uGrFPh7W59nu/4ac=
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java