2012-09-20 33 views
7

Estoy intentando hacer alguna Firma XML firmando solo partes del xml; sin embargo, después de mucha búsqueda no he podido encontrar una solución.Cómo firmar solo una parte específica de XML

Estoy usando Java para firmar un XML usando la transformación Xpath2 y la canonicalización EXCLUSIVA. Si tengo el siguiente código 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> 

y firmarlo, me sale el siguiente resultado (datos reales reemplazados con el maniquí)

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

si validar la firma, todo está bien, sin embargo el problema aquí es justo después de esto realizo un XSLT en el XML que realiza algunos cambios a algunos elementos pero no al elemento firmado (ns0:addr) que se deja intacto. Aunque explícitamente digo que solo se debe firmar el elemento "addr", si intento realizar cambios en cualquiera de sus padres (payload, msg o addr), entonces falla la firma cuando (según mi entender) no debería . Si realizo cambios en otros elementos, como cualquier elemento dentro del encabezado, la firma sigue siendo válida.

He probado la expresión XPath (//*[local-name()='addr']/*) y selecciona los datos correctos a ser firmados (ns2:data) pero parece estar tomando también todos los elementos que conducen a él a partir del elemento raíz (msg, addr).

También he intentado utilizar diferentes transformaciones como UNION pero eso no funciona en absoluto.

¿Alguien sabe cuál es el problema? ¿Hay alguna forma, en Java, de ver exactamente qué se está firmando cuando se firma el XML con fines de depuración?

EDIT:

La carrera XSLT tarde va a hacer las cosas como mover espacios de nombres de la ns0: addr elemento al elemento raíz (MSG) y también se cambia el nombre principal elemento y el espacio de nombres de MSG a newmsg (y un espacio de nombres predeterminado diferente) pero dejando intactos los datos firmados (ns2:data).

El código utilizado para firmar es más o menos el código mencionado aquí http://docs.oracle.com/javase/7/docs/technotes/guides/security/xmldsig/XMLDigitalSignature.html

Excepto que en vez de un ENVUELTO transformo Estoy utilizando un XPATH2 transformar:

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

Y también en lugar de ENVUELTO soy el uso EXCLUSIVO

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

Edit2:

Me han logrado habilitar la depuración fina del proceso xml firma y conseguido lo siguiente:

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>

Parece ser que firma la información correcta, sin embargo, también está agregando algunos espacios de nombres adicionales a la firma que me pregunto si ese es el problema, ya que esos namspaces se toman de los elementos principales.

¿Alguien sabe cómo hacerlo para que no se agreguen todos los espacios de nombres adicionales?

+0

Sí, está firmando el XML completo (solo mirando ''). ¿Puede mostrarnos el código que usa para firmar el documento XML? – dusan

+0

Trataré de poner algo del código más tarde una vez que esté frente a él nuevamente. Sí, el 'uri =" "', sin embargo, esto se debe al uso de xpath en su lugar para seleccionar qué nodo está firmado. ¿No debería ser ese el caso? Además, si cambio otros nodos internos, como el encabezado, la firma sigue siendo válida, lo que me lleva a pensar que algo no está funcionando como debería. – ByteFlinger

+0

Me parece bien. ¿Puedes incluir tu XML después de la transformación xslt? Además, cuando dice que modificó 'msg' o' payload', ¿agregó un nodo secundario o hizo un cambio de nombre? – pd40

Respuesta

1

Después de mucha lucha con XML Signatures finalmente llegué a una solución aceptable (aunque no ideal).

Como resultado, una canonicalización exclusiva no es suficiente. También debe agregar una transformación exclusiva después de todos los demás transformadores. Después de los fragmentos de código que he escrito arriba:

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

Esto hará que sea para que no se adopte cualquier espacios de nombres fuera de los elementos firmados en cuenta (aunque tiene el efecto adicional de que la inserción de espacio de nombre (s) dentro de la elemento firmado está permitido).

También parece que se tendrá en cuenta cualquier elemento en el xpath del elemento firmado, por lo que si tiene el siguiente xpath /root/A/B, firmará la etiqueta B; sin embargo, no podrá cambiar el nombre de la etiqueta A o elementos de raíz.

Esto se puede solucionar utilizando un xpath con menos elementos, como //B.

Creo que puede ser posible superar este problema demasiado aunque hasta ahora no he podido.

0

Hay parámetros relacionados con el espacio de nombres que se pueden pasar al Exclusive XML Canonicalization que describen InclusiveNamespaces PrefixList.

Usted podría intentar hacer pasar un ExcC14NParameterSpec a newCanonicalizationMethod() utilizando una lista de prefijos para ver si eso afecta la canonización de los espacios de nombres.

+1

Gracias. He intentado usar esto: 'List prefixList = new ArrayList (); prefixList.add ("ns2"); C14NMethodParameterSpec c14NMethodParameterSpec = new ExcC14NParameterSpec (prefixList); canonicalisationMethod = xmlSigFactory.newCanonicalizationMethod (CanonicalizationMethod.EXCLUSIVE, c14NMethodParameterSpec); ' pero no se produjo ningún cambio. El signture parece cambiar dependiendo de si agrego más o menos prefijos a la lista, pero todavía no me permite cambiar los elementos encima de lo que debería firmarse. – ByteFlinger

Cuestiones relacionadas