Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 由于更改了XML属性顺序而导致数字签名损坏_Java_Xml_Soap_Digital Signature - Fatal编程技术网

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

Java 由于更改了XML属性顺序而导致数字签名损坏,java,xml,soap,digital-signature,Java,Xml,Soap,Digital Signature,我正在用Java开发一个SOAP Web服务器,其中我的响应必须加上时间戳并签名。要签名的节点是BODY和TIMESTAMP 问题在于XmlSignature.sign方法将这些节点解组,在BODY和TIMESTAMP标记中将namespace属性放在Id属性之前,而由JAX-WS解组的出站响应字符串将namespace属性放在Id之后 因此,这些节点的计算摘要值无效,即: Actual Digest: ljf4iIFTgpHUDKtLjYJEto9Ro5k= Expected Digest:

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

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

因此,这些节点的计算摘要值无效,即:

Actual Digest: ljf4iIFTgpHUDKtLjYJEto9Ro5k=

Expected Digest: iIYWShXDG4o8f/9L08d+apVsGx0=
我想,如果我可以为解组器指定属性的顺序(在签名或响应消息中),我也可以使顺序匹配,但我没有做到这一点

我测试了一个SOAPHandler来截获响应,但没有找到改变消息属性顺序的方法

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


2019-09-19T10:00:00.000Z
2019-09-19T10:05:00.000Z
这是响应中发送的时间戳节点的XML代码:


2019-09-19T10:00:00.000Z
2019-09-19T10:05:00.000Z
身体节点也是如此。 签名:


0
371003
发送:


0
371003
SOAP响应中的完整安全标头:


MIIHDDCCBVYGAWIBAGIQDOHW8DCHSTZYGWILSPZHJANBGKQHKIG9W0BAQSFADCBGGTELMAKGA1EBHMCRVMXQTA
…省略了==
2019-09-19T10:00:00.000Z
2019-09-19T10:05:00.000Z
5yQ7ZdxYjr3pxySKrVbA0/98a4s=
sEY89etI7c+uGrFPh7W59nu/4ac=
CFsbgg+AbV6iiMqWbiZmCacMeZcmcrsW2Eub5B1bUzLsCnygrFZDv/WEI5R3CYS6NVSPNVR7TXG
W235F2mPYSUXFLun/IPYU+0BsMYMLxFF4qMX2pXRFgtXWt9zmhBIf1rl+iuG8mTqUGR0eYMrxW0B
KXPAIGAEUZMWUP7VHCNFPREHR2+N7S4BOVLOSLVFOEKH1TR0NJH1RDR3WYYP8SZEZDZAQMDHKL
QONJQ5zjpaHk/TCMLhiSib+aDAeF4MaT73eo68rM5HNyD4b5EKty+z+bE6GPsS/lR8TFbP0uwLDz
9uKiM0l7fM1ctEd3RORkveXvSXGZlKQ+HKmISA==
这是我用于将数字签名添加到SOAP消息的例程:

/**
*mensaje肥皂公司。
* 
*@param privateKey Clave privada
*@param soapBody Cuerpo de la petición SOAP
*@param nodoSecurity Nodo Security
*@param nodoSecurityTokenReference Nodo SecurityTokenReference
*@param nodoTimestamp Nodo时间戳
* 
*@cgneception Error al generar la firma del mensaje
*/
private static void crearFirmaSeparada(PrivateKey PrivateKey、SOAPBody SOAPBody、SOAPElement节点安全、SOAPElement节点安全令牌引用、,
SOAPElement nodoTimestamp)抛出CgnException
{
字符串uri_算法_摘要=”http://www.w3.org/2000/09/xmldsig#sha1";                 
字符串uri_algoritmo_firma=”http://www.w3.org/2000/09/xmldsig#rsa-sha1”;
字符串uri_算法_转换=”http://www.w3.org/2001/10/xml-exc-c14n#";
字符串uri_algoritmo_canonizacion=”http://www.w3.org/2001/10/xml-exc-c14n#";
试一试{
//在公司的一般情况下,公司的实用性
字符串providerName=System.getProperty(“jsr105Provider”、“org.jcp.xml.dsig.internal.dom.XMLDSigRI”);
Provider=(Provider)Class.forName(providerName).newInstance();
XMLSignatureFactory XMLSignatureFactory=XMLSignatureFactory.getInstance(“DOM”,提供者);
//摘要法
javax.xml.crypto.dsig.DigestMethod DigestMethod=xmlSignatureFactory.newDigestMethod(uri\u algoritmo\u digest,null);
List l_transformaciones=new ArrayList();
//变形金刚
Transform envTransform=xmlSignatureFactory.newTransform(uri\u algoritmo\u transformacion,(TransformParameterSpec)null);
l_transformaciones.add(envTransform);
//引用al时间戳y al正文
字符串id\u key\u info=“KI-1000”;
List l_referenceas=new ArrayList();
Reference refTS=xmlSignatureFactory.newReference(#TS-1000),digestMethod,l#u transformaciones,null,null);
Reference refBody=xmlSignatureFactory.newReference(#Body-1000),digestMethod,l#u transformaciones,null,null);
l_参考添加(参考主体);
l_参考添加(参考文献);
规范化方法cm=xmlSignatureFactory.newCanonicalizationMethod(uri_algoritmo_canonizacion,(C14NMethodParameterSpec)null);
SignatureMethod sm=xmlSignatureFactory.newSignatureMethod(uri\u algoritmo\u firma,null);
SignedInfo SignedInfo=xmlSignatureFactory.newSignedInfo(cm、sm、l_参考);
DOMSignContext signContext=新的DOMSignContext(私钥、节点安全);
signContext.setDefaultNamespacePrefix(“ds”);
signContext.putNamespacePrefix(“http://www.w3.org/2000/09/xmldsig#“,“ds”)
/**
 * 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=