2010-02-11 11 views
19

devo Come viene creato un XML come questoFirma XML: come calcolare il valore digest?

<?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> 

il valore digest (WqpRWHxXA0YgH + p3Sxy6hRo1XIk =) nel riferimento? Voglio dire come posso calcolare questo valore manualmente?

+0

perché vuoi calcolare manualmente? Questo sarà un processo noioso e soggetto a errori. – HerbN

+0

Sto usando le funzioni .net per convalidare la firma. Sta tornando che la firma non è valida. Quindi voglio verificarlo manualmente o se c'era qualche strumento per controllare la firma ... – user252816

+0

Ho capito che hai risolto l'errore "Verifica digest non riuscita per riferimento"? sarebbe possibile ottenere una spiegazione dettagliata di come l'hai fatto? Sto avendo questo problema con un messaggio di sapone firmato usando Metro e un'applicazione WCF netta non riconoscerebbe il valore di digest. –

risposta

-1

This documento deve contenere il modo in cui viene calcolato il valore digest.

Spero che aiuti!

2

Ho riscontrato esattamente questo problema: stavo generando una firma XML in Java & durante la convalida in .NET e la convalida ha sempre avuto esito negativo. Nel mio caso la causa era la funzione 'stampa XML su file' XMLWrite.m (sì, in MATLAB *) che era 'pretty printing' l'XML, inserendo tab, spazi e newline come meglio credeva. Poiché questi sono parte del documento, naturalmente la convalida non è riuscita (anche in Java non è riuscita). Guardando la tua fonte, questo potrebbe accadere a te. Usa un trasformatore (javax.xml.transform. *) Per serializzare correttamente il tuo DOM senza modificare il contenuto.

* Sapevi che MATLAB comprende anche Java? È possibile digitare istruzioni Java nella console dell'interprete & che verranno eseguite come m-code nativo.

+2

Questo è già stato risolto dalla firma XML che si basa su Canonicalizzazione XML. L'XML viene prima normalizzato e le differenze sintattiche (spazi bianchi, spazi dei nomi, ecc.) Verranno gestite correttamente. – ewernli

+1

Vero: ma è il DOM, non la sua seralizzazione, che è stata canonicizzata. I caratteri bianchi extra sono stati inseriti durante la serializzazione (su file) DOPO che il digest è stato calcolato, e erano ancora lì quando il codice di convalida ha creato il suo DOM, lo ha canonicizzato e ricalcolato il digest. Gli spazi bianchi sono significativi nei nodi dei dati dei caratteri analizzati. – Max

16

Mi sono imbattuto in questa domanda quando ho cercato di scoprire la stessa identica cosa. In seguito ho capito come farlo, quindi ho pensato di pubblicare la risposta qui.

Le cose che devono accadere sono:

  • canonica
  • creare valore, tipicamente SHA1 digerire (ma potrebbe essere SHA256 tra gli altri)
  • base64 codificare

La canonica parte era abbastanza semplice, come le librerie Java hanno fatto per me. Quello con cui ho avuto a che fare è stato il prossimo, la creazione del digest, perché ho fatto un errore fatale in quanto il digest SHA1 che ho generato era lo SHA1 in forma HEX. SHA1 è 160 bit, quindi 20 byte, ma se si emettono questi 160 bit in HEX, si ottengono 40 caratteri. Se quindi codifichi base64, ottieni nel valore errato rispetto a quello che dovrebbe essere nel DigestValue.

Invece, è necessario generare il digest SHA1 e codificare Base64 l'output a 20 byte. Non provare ad inviare i 20 byte a STDOUT poiché è altamente improbabile che sia leggibile (motivo per cui le persone spesso emettono l'equivalente HEX, dal momento che è leggibile ). Invece, solo base64 codifica i 20 byte e questo è il tuo DigestValue.

+0

Ho pensato lo stesso, ma ho anche un valore diverso. Hai digerito direttamente Canonicalization Bytes o i byte String digeriti? –

+0

Digestione SHA1 di cosa? – lonelyloner

0

è molto semplice, l'uso OpenSSL nella console:

openssl dgst file di -sha1 -binary | openssl enc -base64

Fatto

+0

OP non ha specificato 'manualmente' come 'programmaticamente'. Questo è comunque un buon modo di controllare. – Vbakke

0

Questa è una soluzione JAVA che richiede i seguenti vasi:

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

Questa soluzione utilizza http://www.w3.org/2001/10/xml-exc-c14n# come algoritmo canonica, e utilizza SHA256 come algoritmo hash e la codifica base64.

Nota: document rappresenta il documento XML come oggetto DOM in JAVA.

Esempio di codice:

 // 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);