XML Signature – Firma Digital sobre XML

24
71455

XML Signature – Firma Digital sobre XML

En este tutorial vamos a ver ejemplos de cómo firmar digitalmente y validar un documento.

Introducción a XML Signature

Con las firmas digitales conseguimos:

  • Integridad: Si la información firmada es modificada, la validación de la firma fallará.
  • No repudiación: La entidad que firmo la información no puede luego decir que no lo hizo.
  • Autentificación: Sabemos qué entidad es la que realizó la firma, pues lo podemos validar con su clave pública.

Además podemos conseguir confidencialidad (cifrado) con el par de claves pública/privada, pues lo que se encripta con la clave privada sólo puede ser descifrado con la clave pública.

Para este tutorial utilizaremos la implementación de Apache (http://xml.apache.org/security/dist/).

Veamos unos ejemplos auto comentados:

  1. Firma digitalmente un documento XML
  2. Validación de un documento firmado digitalmente

Generamos una clave privada y su correspondiente certificado

La herramienta keytool crea pares de claves públicas y privadas, certificados auto firmados, y gestiona almacenes de claves.
Creamos una clave pública/privada:

Clase de utilidades usada en los ejemplos de este tutorial

Ejemplo. Firmamos digitalmente el documento XML

Documento firmado digitalmente (signature.xml).

En el siguiente documento se muestra el documento firmado digitalmente, en donde se puede observar:

  1. La información relacionada con la tarjeta de crédito ha sido sustituida por el elemento xenc:EncryptedData

Ejemplo. Validamos el documento XML digitalmente firmado (signature.xml)

En el siguiente ejemplo vamos a validar el documento que ha sido firmado en el ejemplo anterior.

Como prueba, modifique el documento y observará que el proceso de validación falla debido a que no se cumple la propiedad de integración de la información.

Saludos, Carlos García.

24 Comentarios

  1. Hola Yolanda, te dejo a continuación un ejemplo en C# para validar un XML contra un XSD, espero aun te sirva Saludos desde Morelia, México.

    private void btnValidar_Click(object sender, EventArgs e)
    {
    Resultado = true;
    Accion = VALIDAR;
    txtResultado.Text = \\\»\\\»;
    txtComentarios.Text = \\\»\\\»;
    try
    {

    XmlTextReader xmlR = new XmlTextReader(txtXML.Text);
    XmlValidatingReader xsdR = new XmlValidatingReader(xmlR);
    if (chkXSD.Checked)
    xsdR.Schemas.Add(null, txtXSD.Text);
    xsdR.ValidationType = chkXSD.Checked ? ValidationType.Schema : ValidationType.None;
    xsdR.ValidationEventHandler += new ValidationEventHandler(AdminEventoValidacion);

    while (xsdR.Read())
    {
    Cursor.Current = Cursors.WaitCursor;
    Application.DoEvents();
    }
    Cursor.Current = Cursors.Default;
    xsdR.Close();
    }
    catch (UnauthorizedAccessException ex)
    {
    txtComentarios.Text = ex.Message;
    }
    catch (Exception ex)
    {
    txtComentarios.Text = ex.Message;
    }
    finally
    {
    if (txtComentarios.Text.Trim() == \\\»\\\»)
    {
    if (chkXSD.Checked)
    txtResultado.Text = Resultado ? \\\»Formato de la declaración cumple las especificaciones del esquema\\\» : \\\»Archivo XML incorrecto con respecto al esquema XSD\\\»;
    else
    txtResultado.Text = Resultado ? \\\»La estructura del archivo es correcta\\\» : \\\»Archivo XML mal estructurado\\\»;
    txtComentarios.Text = txtResultado.Text;
    }
    else
    txtResultado.Text = \\\»Esperando validación…\\\»;
    }
    }

  2. El método asociado al evento de validacion, segun sea con respecto al XSD (ValidationType.Schema), o bien para validar la estructura del XML (ValidationType.None)

    private void AdminEventoValidacion(object sender, ValidationEventArgs args)
    {
    Resultado = false;
    txtComentarios.Text += args.Message + \\\»\\\
    \\\
    \\\»;
    }

  3. Hola me podrian enviar o indicar donde puedo bajar los jars para hacer uso de las librerias de firma de xml para utilzar las clases hablo especificamente de las siguientes
    import org.w3c.dom.*;
    import org.apache.xml.security.signature.XMLSignature;
    import org.apache.xml.security.transforms.Transforms;
    import org.apache.xml.security.utils.Constants;

  4. Estimado Carlos
    Estoy investigando este tema y necesito exponerlo para continuar con mis estudios de post-grado y me gustaría tener un demo de tu aplicación, solo que funcione con algún ejemplo que pueda ejecutar en linea. Sé cómo opera el mecanismo de encriptación pero necesito exponerlo a un grupo de compañeros de estudio ¿es posible? respeto toda autoría y mantendría el contacto para seguir esta linea de trabajo en el desarrollo de web semántica.

    Gracias de antemano.
    Adrian Silva

  5. Carlos el tutorial esta muy bueno muy detallado. Necesito extender las funcionalidades de un prototipo de una aplicación para firmar digitalmente archivos XML. Usted podría decirme cuales son las librerías mas utilizada por Jaba para firmar XML. Me seria de gran ayuda su información.
    saludos

  6. Me ha parecido muy interesante y muy util, pero tengo una duda, ¿como puedo validar que el certificado X509 que viaja en el XML está autorizado por una Autoridad certificadora válida que yo tenga almacenada en mi equipo?
    Gracias.

  7. Hola quisiera saber por que la firma es Inválida según la clave pública cuando la valides de la firma ya no es valida, cuando expiro el certificado, existe alguna forma de verificar integridad si la fecha de expiración esta vencida.

  8. hola a todos… tengo un problema con org.apache.xml.security.Init.init(); me salta la excepcion, probé con la librerias xmlSec 1.0.4 , 1.3.0 y 1.5.0 y con todas me bota el mismo error… por favor su ayuda… gracias…

    • Completa con est, el tag es SOAP-ENV:Header:

      Element element = null;
      element = doc.getDocumentElement();
      element.normalize();
      element.getElementsByTagName(«SOAP-ENV:Header»).item(0)
      .appendChild(xmlSignature.getElement());

  9. Hola, necesito ayuda super urgente. Necesito incorporar tags KEYINFO, como se podría incorporar estos tags en el xml firmado? Muchas gracias por el aporte!

  10. Hay alguna manera de implementar
    public static Document loadDocumentFromFile(java.io.File file) throws Exception {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = null;

    factory.setNamespaceAware(true);

    builder = factory.newDocumentBuilder();

    return builder.parse(file);
    }

    en PHP

    • Para UBL 2.0, 2.1, en Invoice debes solamente ubicar el nodo del UBLExtensions mediante los nodos hijos del documento, por ejemplo, en mi caso tengo esta estructura:

      En el java, considerando que el objeto «doc» represemta el xml, accedo al nodo de la firma de la siguiente forma:

      doc.getDocumentElement().getChildNodes().item(3).getChildNodes().item(3).getChildNodes().item(1).appendChild(xmlSignature.getElement());

      Veras que se imprime la firma en ese nodo.

      Saludos

  11. consulta un documento XML firmado se puede importar a otro XML?, si es positivo como se realiza? yo importo pero pierdo la validez de la firma, de la sección del primer documento

  12. Hola Mario,

    Gran ayuda tu codigo para conseguir firmar con Java un xml.

    Estoy tratando de generar un trozo de código que sea capaz de firmar un xml y subirlo directamente a efactura, pero el xml firmado no contine la estructura de firma que efactura espera.

    Me gustaría poder intercambiar contigo ideas y poder colaborar para resolver este problema
    Es posible?

Dejar respuesta

Please enter your comment!
Please enter your name here