2010-02-11 123 views
19

que tienen un XML como estoFirma XML: ¿Cómo calcular el valor de resumen?

<?xml version="1.0" encoding="utf-8"?> 
<foo> 
    <bar> 
    <value>A</value> 
    </bar> 
    <bar> 
    <value>B</value> 
    </bar> 
    <baz> 
    <value>C</value> 
    </baz><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /><Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /><DigestValue>WqpRWHxXA0YgH+p3Sxy6hRo1XIk=</DigestValue></Reference></SignedInfo><SignatureValue>EoRk/GhR4UA4D+8AzGPPkeim1dZrlSy88eF73n/T9Lpeq9IxoGRHNUA8FEwuDNJuz3IugC0n2RHQQpQajiYvhlY3XG+z742pgsdMfFE4Pddk4gF1T8CVS1rsF7bjX+FKT/c8B2/C8FNgmfkxDlB/ochtbRvuAGPQGtgJ3h/wjSg=</SignatureValue><KeyInfo><X509Data><X509Certificate>MIIB8zCCAVygAwIBAgIQgfzbrIjhLL9FobStI2ub3zANBgkqhkiG9w0BAQQFADATMREwDwYDVQQDEwhUZXN0ZUFjbjAeFw0wMDAxMDEwMDAwMDBaFw0zNjAxMDEwMDAwMDBaMBMxETAPBgNVBAMTCFRlc3RlQWNuMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO+yAZ8/qJbhSVH/+2wMmzix3jM/CExb6sTgaiPwe6ylcHgF45zeQDq06OSJZCSns34em/ULINZddDf8z0b9uk/2sOGr1pYqsunLLBvw2FkvWJQDkhx2SzCm8v4xGX2kyXNbjiY/K56oPOMjpayKoAFnnvk7p2iFAxNZK/6lpZ7wIDAQABo0gwRjBEBgNVHQEEPTA7gBCOOHcajwnATYZ0t6w7LVU0oRUwEzERMA8GA1UEAxMIVGVzdGVBY26CEIH826yI4Sy/RaG0rSNrm98wDQYJKoZIhvcNAQEEBQADgYEABL9Qhi6f1Z+/t8oKXBQFx3UUsNF9N2o4k6q1c3CKZYqx2E/in+nARIYRdh5kbeLfomi6GIyVFeXExp8crob3MAzOQMvXf9+ByuezimMPIHDvv0u3kmmeITXfoZrHCDxLoWWlESN1owBfKPqe7JKAuu9ORDC0pUiUfCHWxCoqNos=</X509Certificate></X509Data></KeyInfo></Signature> 
</foo> 

¿Cómo se crea el valor de resumen (WqpRWHxXA0YgH + p3Sxy6hRo1XIk =) en la referencia? Quiero decir, ¿cómo puedo calcular este valor manualmente?

+0

¿Por qué quiere para calcular de forma manual? Ese va a ser un proceso tedioso y propenso a errores. – HerbN

+0

Estoy usando funciones .net para validar la firma. Está volviendo que la firma no es válida. Entonces, quiero verificarlo manualmente o si había alguna herramienta para verificar la firma ... – user252816

+0

¿Entiendo que resolvió el error de "Verificación incompleta para la referencia"? ¿sería posible obtener una explicación detallada de cómo lo hizo en realidad? Estoy teniendo ese problema con un mensaje de jabón firmado usando Metro y una aplicación .Net WCF no reconocería el valor del resumen. –

Respuesta

-1

This documento debe contener cómo se calcula el valor de resumen.

Espero que ayude!

2

He encontrado exactamente este problema yo mismo: estaba generando una firma XML en Java & validando en .NET, y la validación siempre falló. En mi caso, la causa fue la función 'print XML to file' XMLWrite.m (sí, en MATLAB *) que estaba 'imprimiendo bastante' el XML, insertando pestañas, espacios y líneas nuevas como lo consideraba conveniente. Dado que estos son parte del documento, naturalmente la validación falló (falló en Java, también). En cuanto a su fuente, esto puede estar sucediendo a usted. Utilice un transformador (javax.xml.transform. *) Para serializar su DOM correctamente sin cambiar el contenido.

* ¿Sabía que MATLAB también entiende Java? Puede simplemente escribir las sentencias de Java en la consola del intérprete & que se ejecutarán como el código m nativo.

+2

Esto ya está cubierto por XML Signature, que se basa en XML Canonicalization. Primero, XML se normaliza y las diferencias sintácticas (espacios en blanco, espacios de nombres, etc.) se manejarán correctamente. – ewernli

+1

Verdad: pero es el DOM, no su serralización, que ha sido canonicalizado. Los caracteres extra de espacio en blanco se insertaron durante la serialización (en el archivo) DESPUÉS de que se calculó el resumen, y todavía estaban allí cuando el código de validación creó su DOM, lo canonicalizó y recalculó el resumen. El espacio en blanco es significativo en los nodos de datos de caracteres analizados. – Max

16

Me encontré con esta pregunta al intentar encontrar exactamente lo mismo. Luego resolví cómo hacerlo, así que pensé que publicaría la respuesta aquí.

Las cosas que deben ocurrir son:

  • Canonicalización
  • crear valor de resumen, por lo general SHA1 (pero podría ser sha256 entre otros)
  • base 64 codificarlo

La canonicalización parte fue bastante simple, ya que las bibliotecas de Java hicieron eso por mí. Lo que tuve problemas fue el siguiente, la creación del resumen, porque cometí un error fatal en el sentido de que el resumen de SHA1 que generé fue el SHA1 en forma HEX. SHA1 tiene 160 bits, entonces 20 bytes, pero si saca estos 160 bits en HEX, obtendrá 40 caracteres. Si luego base64 codifica eso, obtendrá totalmente el valor incorrecto en comparación con lo que debería estar en DigestValue.

En su lugar, debe generar el resumen SHA1 y base64 codificar la salida de 20 bytes. No intente dar salida a los 20 bytes a STDOUT, ya que es muy poco probable que sean legibles (razón por la cual la gente suele generar el equivalente HEX, ya que es legible). En cambio, solo base64 codifica los 20 bytes y ese es tu DigestValue.

+0

Pensé lo mismo, pero también recibo un valor diferente. ¿Digeriste directamente los bytes de canonización o los bytes de cadenas digeridos? –

+0

¿Digerir SHA1 de qué? – lonelyloner

0

es muy simple, el uso de OpenSSL en la consola:

openssl DGST archivo -sha1 -binary | openssl enc -base64

Hecho

+0

OP no especificó 'manualmente' como 'programáticamente'. Esto es de todos modos una buena manera de verificar. – Vbakke

0

Esta es una solución JAVA que requiere los siguientes frascos:

  • commons-logging-1.2.jar
  • commons-codec-1.6.jar
  • Saxon-HE-9.4.jar
  • xmlsec-1.3.0.jar

Esta solución utiliza http://www.w3.org/2001/10/xml-exc-c14n# como el algoritmo de canonicalización, y utiliza SHA256 como el algoritmo de hash y codificación base64.

Nota: document representa el documento XML como un objeto DOM en JAVA.

Ejemplo de código:

 // create the transformer in order to transform the document from 
     // DOM Source as a JAVA document class, into a character stream (StreamResult) of 
     // type String writer, in order to be converted to a string later on 
     TransformerFactory tf = new net.sf.saxon.TransformerFactoryImpl(); 
     Transformer transformer = tf.newTransformer(); 
     transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
     transformer.setOutputProperty(OutputKeys.METHOD, "xml"); 
     transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 

     // create the string writer and transform the document to a character stream 
     StringWriter sw = new StringWriter(); 
     transformer.transform(new DOMSource(document), new StreamResult(sw)); 

     String documentAsString = sw.toString(); 

     // initialize the XML security object, which is necessary to run the apache canonicalization 
     com.sun.org.apache.xml.internal.security.Init.init(); 

     // canonicalize the document to a byte array and convert it to string 
     Canonicalizer canon = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); 
     byte canonXmlBytes[] = canon.canonicalize(documentAsString.getBytes()); 
     String canonXmlString = new String(canonXmlBytes); 

     // get instance of the message digest based on the SHA-256 hashing algorithm 
     MessageDigest digest = MessageDigest.getInstance("SHA-256"); 

     // call the digest method passing the byte stream on the text, this directly updates the message 
     // being digested and perform the hashing 
     byte[] hash = digest.digest(canonXmlString.getBytes(StandardCharsets.UTF_8)); 

     // encode the endresult byte hash 
     byte[] encodedBytes = Base64.encodeBase64(hash); 

     return new String(encodedBytes); 
Cuestiones relacionadas