2012-09-20 12 views
7

Ich versuche, einige XML-Signatur zu machen, indem ich nur Teile des XML unterschreibe, aber nach vielen Suchen konnte ich keine Lösung finden.Wie man nur einen bestimmten Teil von XML signiert

Ich benutze Java, um ein XML mit Xpath2-Transformation und EXCLUSIVE-Kanonisierung zu signieren. Wenn ich die folgende 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> 

haben und es unterzeichnen, erhalte ich die folgende Ausgabe (Real mit Dummy ersetzt Daten)

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

Wenn ich die Unterschrift bestätigen, alles ist in Ordnung, aber hier ist das Problem Ich führe gleich danach eine XSLT in der XML durch, die einige Änderungen an einigen Elementen vornimmt, aber nicht am signierten Element (ns0:addr), das intakt bleibt. Auch wenn ich explizit sage, dass nur das "addr" -Element signiert sein sollte, wenn ich versuche, Änderungen an einem seiner Eltern durchzuführen (payload, msg oder addr), dann versagt es die Signatur, wenn (nach meinem Verständnis) sollte es nicht . Wenn ich Änderungen an anderen Elementen, z. B. an Elementen innerhalb des Headers, vornimmt, ist die Signatur weiterhin gültig.

Ich habe den XPath-Ausdruck (//*[local-name()='addr']/*) getestet und es wählt die korrekten Daten (ns2:data) unterzeichnet werden, aber es scheint auch aus dem Wurzelelement (msg, addr) ausgehend, das dazu führen, alle Elemente dauern.

Ich habe auch versucht, verschiedene Transformationen wie UNION zu verwenden, aber das funktioniert überhaupt nicht.

Weiß jemand, was das Problem sein könnte? Gibt es eine Möglichkeit in Java, genau zu sehen, was beim Signieren des XML zu Debuggingzwecken signiert wird?

EDIT:

Die Xslt laufen später tun werden Dinge wie Namespaces aus dem ns0 bewegen: addr Element mit dem Wurzelelement (msg) und auch wird es das Hauptelement Namen und Namespace von msg newmsg sich ändern (und einen anderen Standard-Namensraum), aber die signierten Daten (ns2:data) intakt lassen.

Der Code verwendet, es zu unterzeichnen ist mehr oder weniger der Code hier erwähnt http://docs.oracle.com/javase/7/docs/technotes/guides/security/xmldsig/XMLDigitalSignature.html

Außer anstelle eines umhüllte verwandeln ich ein xpath2 verwandeln bin mit:

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

Und auch anstelle von umhüllten Ich bin mit EXCLUSIVE

canonicalisationMethod = fac.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE, (C14NMethodParameterSpec) null); 

EDIT2:

Ich habe es geschafft feinere Debuggen des xml Signierung zu ermöglichen und bekam die folgende:

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>

Es scheint jedoch, die richtigen Daten Unterzeichnung zu sein, wird auch einige zusätzliche Namespaces auf die Signatur hinzugefügt, die mich macht sich fragen Wenn das der Fall ist, da diese Namespaces aus den Elternelementen stammen.

Jeder weiß, wie man es nicht alle zusätzlichen Namespaces hinzugefügt bekommen?

+0

Ja, Sie signieren das komplette XML (nur indem Sie auf '') schauen. Können Sie uns den Code zeigen, mit dem Sie das XML-Dokument signieren? – dusan

+0

Ich werde versuchen, etwas Code später, wenn ich wieder davor bin. Ja, das 'uri =" ", aber das liegt daran, dass stattdessen xpath verwendet wird, um auszuwählen, welcher Knoten signiert ist. Sollte das nicht der Fall sein? Auch wenn ich andere innere Knoten wie Header ändere, ist die Signatur immer noch gültig, was zu der Annahme führt, dass etwas nicht so funktioniert, wie es sein sollte. – ByteFlinger

+0

Es sieht OK für mich aus. Können Sie Ihr XML nach der xslt-Transformation auflisten? Wenn Sie sagen, dass Sie 'msg' oder' payload' modifiziert haben, haben Sie einen Kind-Knoten hinzugefügt oder eine Umbenennung vorgenommen? – pd40

Antwort

1

Nach vielen Kämpfen mit XML-Signaturen kam ich endlich zu einer akzeptablen Lösung (wenn auch nicht ideal).

Wie sich herausstellt, ist eine Exklusiv-Kanonisierung nicht genug. Sie müssen auch eine exklusive Transformation nach allen anderen Transformatoren hinzufügen. Im Anschluss an den Code-Schnipsel ich oben schrieb:

List<Transform> transforms = new ArrayList<Transform>() 
transforms.add(transform) 
fac.newTransform(CanonicalizationMethod.EXCLUSIVE, (TransformParameterSpec) null) 

Dadurch wird es so, dass alle andere Namensräume außerhalb der signierten Elemente nicht berücksichtigt werden (obwohl es den zusätzlichen Effekt hat, den Namensraum eingefügt (n) in der signiertes Element ist erlaubt).

Es scheint auch, dass jedes Element im Xpath zum signierten Element berücksichtigt wird. Wenn Sie also den folgenden xpath /root/A/B haben, wird es Tag B signieren, aber Sie können den Tag-Namen von A oder nicht ändern Wurzelelemente.

Dies kann durch Verwendung eines xpath mit weniger Elementen wie //B überwunden werden.

Ich glaube, dass es möglich sein könnte, dieses Problem zu überwinden, obwohl ich bisher nicht in der Lage war.

0

Es gibt Parameter, die sich auf den Namespace beziehen und an Exclusive XML Canonicalization übergeben werden können, die InclusiveNamespaces PrefixList beschreiben.

könnten Sie versuchen, eine ExcC14NParameterSpec zu newCanonicalizationMethod() über ein Präfix Liste zu sehen, ob das die Kanonisierung der Namensräume betrifft.

+1

Danke. Ich habe versucht, dies zu verwenden: 'Liste prefixList = neue ArrayList (); prefixList.add ("ns2"); C14NMethodParameterSpec c14NMethodParameterSpec = new ExcC14NParameterSpec (prefixList); canonicalisationMethod = xmlSigFactory.newCanonizationizationMethod (CanonicalizationMethod.EXCLUSIVE, c14NMethodParameterSpec); ' aber keine Änderung passiert ist. Die Signatur scheint sich zu ändern, je nachdem, ob ich mehr oder weniger Präfixe zur Liste hinzufüge, aber es erlaubt mir immer noch nicht, die Elemente über dem zu ändern, was signiert werden soll. – ByteFlinger

Verwandte Themen