Sto provando a fare un po 'di firma XML firmando solo parti dell'xml ma dopo molte ricerche non sono stato in grado di trovare una soluzione.Come firmare solo una parte specifica di XML
Sto usando java per firmare un XML utilizzando la trasformata Xpath2 e la canonicalizzazione ESCLUSIVA. Se ho il seguente codice XML
<?xml version="1.0" encoding="UTF-8"?>
<msg xmlns="http://someaddress/ad/m1" xmlns:ns1="http://someotheraddres/ad/m2" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#">
<header>
<id>wsfrwerwerwer</id>
<name>addr</name>
<somenode>
<trace>ND</trace>
</somenode>
</header>
<payload><ns0:addr xmlns:ns0="http://someaddres/ad/m3"><ns2:data xmlns:ns2="http://someaddres/ad/m3">
<ns2:name>somevalue</ns2:name>
<ns2:value>354</ns2:value>
</ns2:data>
</ns0:addr>
</payload>
</msg>
e firmare, ottengo il seguente output (dati reali sostituiti con il manichino)
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<msg xmlns="http://someaddress/ad/m1" xmlns:ns1="http://someotheraddres/ad/m2" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#">
<header>
<id>wsfrwerwerwer</id>
<name>addr</name>
<somenode>
<trace>ND</trace>
</somenode>
</header>
<payload>
<ns0:addr xmlns:ns0="http://someaddres/ad/m3">
<ns2:data xmlns:ns2="http://someaddres/ad/m3">
<ns2:name>somevalue</ns2:name>
<ns2:value>354</ns2:value>
</ns2:data>
</ns0:addr>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2002/06/xmldsig-filter2">
<XPath xmlns="http://www.w3.org/2002/06/xmldsig-filter2" xmlns:ns0="http://someaddres/ad/m3" Filter="intersect">//*[local-name()='addr']/*</XPath>
</Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<DigestValue>sdlfjdeklsdfngf</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>femhjgklnlkl</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>swerwerwrwerwerwe</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
</payload>
</msg>
Se convalidare la firma, è tutto a posto ma il problema qui è subito dopo eseguo un XSLT nell'XML che esegue alcune modifiche ad alcuni elementi ma non l'elemento firmato (ns0:addr
) che viene lasciato intatto. Anche se dichiaro esplicitamente che solo l'elemento "addr" dovrebbe essere firmato, se provo a eseguire modifiche a uno dei suoi genitori (payload
, msg
o addr
), fallisce la firma quando (secondo la mia comprensione) non dovrebbe . Se eseguo modifiche ad altri elementi come qualsiasi cosa all'interno dell'intestazione, la firma è ancora valida.
Ho testato l'espressione XPath (//*[local-name()='addr']/*
) e seleziona i dati corretti da firmare (ns2:data
) ma sembra essere lento anche tutti gli elementi che conducono ad esso a partire dall'elemento radice (msg
, addr
).
Ho anche provato a utilizzare diverse trasformazioni come UNION ma questo non funziona affatto.
Qualcuno sa quale potrebbe essere il problema? C'è un modo, in Java, per vedere esattamente ciò che viene firmato quando si firma il codice XML per scopi di debug?
EDIT:
La corsa XSLT poi farà le cose come spostare gli spazi dei nomi dal ns0: addr elemento con l'elemento radice (msg) ed inoltre sarà cambiare il nome dell'elemento principale e dello spazio dei nomi da msg al newmsg (e un diverso spazio dei nomi predefinito) ma lasciando intatti i dati firmati (ns2:data
).
Il codice utilizzato per firmare è più o meno il codice di cui qui http://docs.oracle.com/javase/7/docs/technotes/guides/security/xmldsig/XMLDigitalSignature.html
tranne che invece di un AVVOLTO trasformo Sto utilizzando un XPATH2 trasformare:
Map<String, String> namespaceMap = new HashMap<String, String>(0);
namespaceMap.put("ns0", "http://someaddres/ad/m3");
XPathType xPathType = new XPathType(xPathParameters, Filter.INTERSECT, namespaceMap);
List<XPathType> xPathList = new ArrayList<XPathType>(0);
xPathList.add(xPathType)
XPathFilter2ParameterSpec xPathFilter2ParameterSpec = new XPathFilter2ParameterSpec(xPathList);
transform = fac.newTransform(CanonicalizationMethod.XPATH2, xPathFilter2ParameterSpec);
E anche al posto di AVVOLTO Sono utilizzando ESCLUSIVO
canonicalisationMethod = fac.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE, (C14NMethodParameterSpec) null);
EDIT2:
Sono riuscito a attivare il debug più fine del processo xml firma e ha ottenuto la seguente:
FINER: Pre-digested input: 21-Sep-2012 10:51:39 org.jcp.xml.dsig.internal.DigesterOutputStream write FINER: <ns2:data xmlns="http://someaddress/ad/m1" xmlns:ns0="http://someaddres/ad/m3" xmlns:ns1="http://someotheraddres/ad/m2" xmlns:ns2="http://someaddres/ad/m3"> <ns2:name>somevalue</ns2:name> <ns2:value>354</ns2:value> </ns2:data>
Sembra essere la firma e la correttezza dei dati tuttavia è anche l'aggiunta di alcuni spazi dei nomi in più per la firma, che mi fa chiedere se questo è il problema dal momento che quei namspace sono presi dagli elementi genitore.
Qualcuno sa come fare a non aggiungere tutti gli spazi dei nomi aggiuntivi?
Sì, stai firmando l'XML completo (solo guardando ''). Puoi mostrarci il codice che usi per firmare il documento XML? –
dusan
Proverò a inserire un po 'di codice più tardi una volta che mi troverò di nuovo davanti a esso. Sì, 'uri =" "' tuttavia questo è dovuto all'utilizzo di xpath per selezionare quale nodo è stato firmato. Non dovrebbe essere così? Inoltre, se cambio altri nodi interni come l'intestazione, la firma è ancora valida e ciò mi porta a credere che qualcosa stia funzionando, ma non come dovrebbe essere. – ByteFlinger
Mi sembra a posto. Puoi elencare il tuo XML dopo la trasformazione xslt? Inoltre, quando dici di aver modificato 'msg' o' payload', hai aggiunto un nodo figlio o fatto un rinominare? – pd40