public final class AOXAdESSigner
extends java.lang.Object
implements es.gob.afirma.core.signers.AOSigner
Soporta XAdES-BES y XAdES-EPES.
Debido a errores en algunas versiones del entorno de ejecución de Java, esta clase puede generar ocasionalmente
mensajes en consola del tipo: [Fatal Error] :1:1: Content is not allowed in prolog.
. Estos
deben ignorarse, ya que no indican ninguna condición de error ni malfuncionamiento.
Los atributos específicos XAdES implementados por esta clase (además de los relativos a las politicas de firma) son:
Distintos formatos de firmas XML
La firma XML en modo Detached permite tener una firma de forma separada e independiente del
contenido firmado, pudiendo relacionar firma con contenido firmado mediante una referencia de tipo
URI. Este tipo de firmas es útil cuando no se puede modificar el contenido original pero se
desea constatar su autenticidad, procedencia, etc.
Un uso común de este formato es en la descarga de ficheros, pudiendo poner a disposición del internauta, junto al contenido a descargar, un pequeño fichero de firma para verificar la integridad del primero.
Un ejemplo de este tipo de firmas sería la siguiente estructura (resumida) XML:
<?xml version="1.0" encoding="UTF-8"?> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <ds:Reference URI="http://www.mpt.es/contenido"> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <ds:DigestValue/> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue/> </ds:Signature>
En este ejemplo, los datos firmados se encuentran en un servidor Web accesible públicamente: http://www.mpt.es/contenido, y se referencia como tal, conformando lo que se denomina Externally Detached o "Detached Externa".
Cuando se desea firmar un contenido con un formato Detached, pero se quiere eliminar la dependencia de la disponibilidad externa del contenido firmado, es posible crear una estructura XML que contenga los propios contenidos y la firma, pero cada uno en una subestructura independiente, manteniendo asi el concepto de Detached (firma y contenido firmado no se interrelacionan directamente). Para adecuarse al estándar los nodos de firma y contenido debe encontrarse en el mismo nivel dentro del XML.
Un ejemplo de esta estructura XML sería:
<?xml version="1.0" encoding="UTF-8"?> <internally-detached> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <ds:Reference URI="#data"> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <ds:DigestValue/> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue/> </ds:Signature> <document Id="data"> <title>title</title> <author>writer</author> <date>today</date> <content> <para>First paragraph</para> <para>Second paragraph</para> </content> </document> </internally-detached>
En este caso, la estructura internally-detached contiene dos subestructuras, la firma (Signature) y el propio contenido firmado (document). La forma de relacionar ambos es, como ocurría en el primer ejemplo, con una URI, solo que en este caso es interna al documento XML, referenciando el identificador de la subestructura del contenido firmado (data).
A esta variante de firma Detached se la conoce como Internally Detached, o "Detached Interna".
Para unificar las superestructuras creadas dentro de un formato "Detached Interno", el Cliente @firma construye siempre el siguiente esqueleto XML:
<CONTENT Id="id" Encoding="codificacion" MimeType="MimeType" Algorithm=""> <! CONTENIDO FIRMADO --> </CONTENT>
Es decir, el contenido a firmar, ya sea XML o no-XML, se encapsula dentro de una etiqueta XML llamada CONTENT, en la que se indica la codificación del contenido (UTF-8, Base64, etc.), el tipo de contenido (imagen JPEG, texto, XML, etc.) y el algoritmo utilizado para calcular la huella digital de este (por ejemplo, SHA-1).
Como la superestructura es XML, si el contenido también es XML la inserción es directa (como en el primer ejemplo de "Detached Interna", pero si no es XML se codifica en Base64 antes de insertarse, resultando una estructura con una forma similar a la siguiente:
<CONTENT Id="id" Encoding="Base64" MimeType="application/octect-stream" Algorithm=""> SFGJKASGFJKASEGUYFGEYGEYRGADFJKASGDFSUYFGAUYEGWEYJGDFYKGYKGWJKEGYFWYJ= </CONTENT>
La larga cadena de caracteres sería una codificación Base64 del original interpretado en su forma binaria pura.
Otra variante de firma es la Enveloping, en la que la estructura XML de firma es la única en el documento de firma, y esta contiene internamente el contenido firmado (en un nodo propio).
<?xml version="1.0" encoding="UTF-8"?> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <ds:Reference URI="#obj"> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <ds:DigestValue/> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue/> <ds:Object Id="obj">SFGJKASGFJKASEGUYFGEYGEYRGADFJKASGDFSUYFG=</ds:Object> </ds:Signature>
En este caso, los datos firmados se encuentran en el nodo Object, referenciados internamente al XML mediante el identificador obj.
Al igual que ocurría con el formato Detached, si los datos no son XML, no es posible insertarlos directamente dentro de una estructura XML, por lo que se codifican previamente en Base64.
Este formato de firma XMLDSig está pensado para que un contenido XML pueda auto-contener su propia firma digital, insertándola en un nodo propio interno, por lo que, al contrario que en los formatos anteriores, no es posible firmar contenido que no sea XML.
Un ejemplo simple del resultado de una firma Enveloped podría ser el siguiente:
<!DOCTYPE Enveloped [ <!ENTITY ds "http://www.w3.org/2000/09/xmldsig#"> <!ENTITY c14n "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"> <!ENTITY enveloped "http://www.w3.org/2000/09/xmldsig#enveloped-signature"> <!ENTITY xslt "http://www.w3.org/TR/1999/REC-xslt-19991116"> <!ENTITY digest "http://www.w3.org/2000/09/xmldsig#sha1"> ]> <Letter> <Return-address>address</Return-address> <To>You</To> <Message>msg body</Message> <From> <ds:Signature xmlns:ds="ds"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <ds:Reference URI=""> <ds:Transforms> <ds:Transform Algorithm="enveloped"></ds:Transform> </ds:Transforms> <ds:DigestMethod Algorithm="digest"/> <ds:DigestValue></ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue/> </ds:Signature> </From> <Attach>attachement</Attach> </Letter>
En este caso, el documento original (Letter), contiene internamente la estructura de firma digital (Signature).
Una peculiaridad de la estructura generada es que esta referenciada mediante una URI vacía
(URI=""
), lo cual indica que la firma aplica a la totalidad del documento original.
Modifier and Type | Field and Description |
---|---|
static java.lang.String |
SIGNATURE_TAG
Etiqueta de los nodos firma de los XML firmados.
|
Constructor and Description |
---|
AOXAdESSigner() |
Modifier and Type | Method and Description |
---|---|
byte[] |
cosign(byte[] data,
byte[] sign,
java.lang.String algorithm,
java.security.PrivateKey key,
java.security.cert.Certificate[] certChain,
java.util.Properties xParams)
Cofirma datos en formato XAdES.
|
byte[] |
cosign(byte[] sign,
java.lang.String algorithm,
java.security.PrivateKey key,
java.security.cert.Certificate[] certChain,
java.util.Properties extraParams)
Cofirma datos en formato XAdES.
|
byte[] |
countersign(byte[] sign,
java.lang.String algorithm,
es.gob.afirma.core.signers.CounterSignTarget targetType,
java.lang.Object[] targets,
java.security.PrivateKey key,
java.security.cert.Certificate[] certChain,
java.util.Properties xParams)
Contrafirma firmas en formato XAdES.
|
byte[] |
getData(byte[] sign) |
java.lang.String |
getSignedName(java.lang.String originalName,
java.lang.String inText) |
es.gob.afirma.core.util.tree.AOTreeModel |
getSignersStructure(byte[] sign,
boolean asSimpleSignInfo) |
es.gob.afirma.core.signers.AOSignInfo |
getSignInfo(byte[] sign) |
static boolean |
isDetached(org.w3c.dom.Element element)
Comprueba si la firma es detached.
|
static boolean |
isEnveloped(org.w3c.dom.Element element)
Comprueba si la firma es enveloped.
|
static boolean |
isEnveloping(org.w3c.dom.Element element)
Comprueba si la firma es enveloping.
|
boolean |
isSign(byte[] sign) |
boolean |
isValidDataFile(byte[] data) |
byte[] |
sign(byte[] data,
java.lang.String algorithm,
java.security.PrivateKey key,
java.security.cert.Certificate[] certChain,
java.util.Properties xParams)
Firma datos en formato XAdES.
|
public static final java.lang.String SIGNATURE_TAG
public byte[] sign(byte[] data, java.lang.String algorithm, java.security.PrivateKey key, java.security.cert.Certificate[] certChain, java.util.Properties xParams) throws es.gob.afirma.core.AOException
Este método, al firmar un XML, firmas también sus hojas de estilo XSL asociadas, siguiendo el siguiente criterio:
sign
in interface es.gob.afirma.core.signers.AOSimpleSigner
data
- Datos que deseamos firmar.algorithm
- Algoritmo a usar para la firma.
Se aceptan los siguientes algoritmos en el parámetro algorithm
:
key
- Clave privada a usar para firmar.certChain
- Cadena de certificados del clientexParams
- Parámetros adicionales para la firma (detalle)es.gob.afirma.core.AOException
- Cuando ocurre cualquier problema durante el procesopublic static boolean isDetached(org.w3c.dom.Element element)
element
- Elemento que contiene el nodo raíz del documento que se
quiere comprobartrue
si la firma es detached, false
en caso contrario.public static boolean isEnveloped(org.w3c.dom.Element element)
element
- Elemento que contiene el nodo raíz del documento que se
quiere comprobartrue
cuando la firma es enveloped, false
en caso
contrario.public static boolean isEnveloping(org.w3c.dom.Element element)
element
- Elemento que contiene el nodo raíz del documento que se
quiere comprobar.true
cuando la firma es enveloping, false
en caso
contrario.public byte[] getData(byte[] sign) throws es.gob.afirma.core.AOInvalidFormatException
getData
in interface es.gob.afirma.core.signers.AOSigner
es.gob.afirma.core.AOInvalidFormatException
public byte[] cosign(byte[] data, byte[] sign, java.lang.String algorithm, java.security.PrivateKey key, java.security.cert.Certificate[] certChain, java.util.Properties xParams) throws es.gob.afirma.core.AOException
Este método firma todas las referencias a datos declaradas en la firma original, ya apunten estas a datos, hojas de estilo o cualquier otro elemento. En cada referencia firmada se introduciran las mismas transformaciones que existiesen en la firma original.
A nivel de formato interno, cuando cofirmamos un documento ya firmado previamente, esta
firma previa no se modifica. Si tenemos en cuenta que XAdES es en realidad un subconjunto
de XMLDSig, el resultado de una cofirma XAdES sobre un documento firmado previamente con
XMLDSig (o viceversa), son dos firmas independientes, una en XAdES y otra en XMLDSig.
Dado que todas las firmas XAdES son XMLDSig pero no todas las firmas XMLDSig son XAdES,
el resultado global de la firma se adecúa al estandar mas amplio, XMLDSig en este caso.
cosign
in interface es.gob.afirma.core.signers.AOCoSigner
data
- No se utiliza.sign
- Documento con las firmas iniciales.algorithm
- Algoritmo a usar para la firma.
Se aceptan los siguientes algoritmos en el parámetro algorithm
:
key
- Clave privada a usar para firmar.certChain
- Cadena de certificados del cliente.xParams
- Parámetros adicionales para la firma (detalle)es.gob.afirma.core.AOException
- Cuando ocurre cualquier problema durante el procesopublic byte[] cosign(byte[] sign, java.lang.String algorithm, java.security.PrivateKey key, java.security.cert.Certificate[] certChain, java.util.Properties extraParams) throws es.gob.afirma.core.AOException
Este método firma todas las referencias a datos declaradas en la firma original, ya apunten estas a datos, hojas de estilo o cualquier otro elemento. En cada referencia firmada se introduciran las mismas transformaciones que existiesen en la firma original.
A nivel de formato interno, cuando cofirmamos un documento ya firmado previamente, esta
firma previa no se modifica. Si tenemos en cuenta que XAdES es en realidad un subconjunto
de XMLDSig, el resultado de una cofirma XAdES sobre un documento firmado previamente con
XMLDSig (o viceversa), son dos firmas independientes, una en XAdES y otra en XMLDSig.
Dado que todas las firmas XAdES son XMLDSig pero no todas las firmas XMLDSig son XAdES,
el resultado global de la firma se adecúa al estandar mas amplio, XMLDSig en este caso.
cosign
in interface es.gob.afirma.core.signers.AOCoSigner
sign
- Documento con las firmas iniciales.algorithm
- Algoritmo a usar para la firma.
Se aceptan los siguientes algoritmos en el parámetro algorithm
:
key
- Clave privada a usar para firmar.certChain
- Cadena de certificados del firmante.extraParams
- Parámetros adicionales para la firma (detalle)es.gob.afirma.core.AOException
- Cuando ocurre cualquier problema durante el procesopublic byte[] countersign(byte[] sign, java.lang.String algorithm, es.gob.afirma.core.signers.CounterSignTarget targetType, java.lang.Object[] targets, java.security.PrivateKey key, java.security.cert.Certificate[] certChain, java.util.Properties xParams) throws es.gob.afirma.core.AOException
Este método contrafirma los nodos de firma indicados de un documento de firma.
countersign
in interface es.gob.afirma.core.signers.AOCounterSigner
sign
- Documento con las firmas iniciales.algorithm
- Algoritmo a usar para la firma.
Se aceptan los siguientes algoritmos en el parámetro algorithm
:
targetType
- Mecanismo de selección de los nodos de firma que se deben
contrafirmar.
Las distintas opciones son:
target
target
Cada uno de estos tipos se define en CounterSignTarget
.
targets
- Listado de nodos o firmantes que se deben contrafirmar según el
targetType
seleccionado.key
- Clave privada a usar para firmar.certChain
- Cadena de certificados del firmante.xParams
- Parámetros adicionales para la firma (detalle)es.gob.afirma.core.AOException
- Cuando ocurre cualquier problema durante el procesopublic es.gob.afirma.core.util.tree.AOTreeModel getSignersStructure(byte[] sign, boolean asSimpleSignInfo) throws es.gob.afirma.core.AOInvalidFormatException
getSignersStructure
in interface es.gob.afirma.core.signers.AOSigner
es.gob.afirma.core.AOInvalidFormatException
public boolean isSign(byte[] sign)
isSign
in interface es.gob.afirma.core.signers.AOSigner
public boolean isValidDataFile(byte[] data)
isValidDataFile
in interface es.gob.afirma.core.signers.AOSigner
public java.lang.String getSignedName(java.lang.String originalName, java.lang.String inText)
getSignedName
in interface es.gob.afirma.core.signers.AOSigner
public es.gob.afirma.core.signers.AOSignInfo getSignInfo(byte[] sign) throws es.gob.afirma.core.AOException
getSignInfo
in interface es.gob.afirma.core.signers.AOSigner
es.gob.afirma.core.AOException