为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

PIPIONE 2023-08-09 15:48:05
我正在用 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>
查看完整描述

1 回答

?
胡说叔叔

TA贡献1804条经验 获得超8个赞

经过几天的努力,我终于找到了问题所在。


为了对正文进行签名,我必须为标签分配一个 ID,以及在 tar 下对此 ID 的引用。


所以我的 XML 看起来像这样:


...


之后,我用我的私钥签署了传出消息。


这是我将 Id 属性添加到 Body 标记的函数:


/**

 * Asigna un identificador único al nodo Body del mensaje.

 * 

 * @param soapMessage                       Mensaje SOAP

 * 

 * @throws SOAPException

 */

private static void asignarIdNodoBody(SOAPMessage soapMessage) throws SOAPException {

    String idBody = "Body-123456";

    SOAPBody soapBody = soapMessage.getSOAPBody();

    soapBody.setAttributeNS(NAMESPACE_WSU, "wsu:Id", id_body);

}

由于某种我不明白的奇怪原因,上面的代码导致添加的数字签名没有通过验证。


我用这个函数替换了上面的函数:


/**

 * Asigna un identificador único al nodo Body del mensaje.

 * 

 * @param soapMessage                       Mensaje SOAP

 * 

 * @throws SOAPException

 */

private static void asignarIdNodoBody(SOAPMessage soapMessage) throws SOAPException {

    String idBody = "Body-123456";

    SOAPBody soapBody = soapMessage.getSOAPBody();

    SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart().getEnvelope();

    Name name = soapEnvelope.createName("Id", "wsu", NAMESPACE_WSU);


    soapBody.addAttribute(name, id_body);

}

瞧!我之后添加了数字签名,现在它通过了验证。


Referencia [0] 

    URI:              #Body-123456

    Validacion OK:    true 

    Digest:           JMdmg+d/yJJA1wg7yzDctIBE9z4= 

    Expected digest:  JMdmg+d/yJJA1wg7yzDctIBE9z4= 

Referencia [1] 

    URI:              #TS-1000 

    Validacion OK:    true 

    Digest:           sEY89etI7c+uGrFPh7W59nu/4ac= 

    Expected digest:  sEY89etI7c+uGrFPh7W59nu/4ac=


查看完整回答
反对 回复 2023-08-09
  • 1 回答
  • 0 关注
  • 58 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信