Evaluando propuestas

Firma electronica avanzada

Publicado el 30 Mayo, 2019 en Programación y Tecnología

Sobre este proyecto

Abierto

Se necesita implementar una firma electronica avanzada a unos documentos de una web .

Datos encontrados para entender lo que se necesita:

Firma electrónica avanzada: una firma electrónica se considera avanzada si cumple con ciertos requisitos: Proporciona información de identificación única que la vincula a su firmante. El firmante tiene el control exclusivo de los datos utilizados para crear la firma electrónica. Debe ser capaz de identificar si los datos que acompañan el mensaje han sido manipulados después de haber sido firmados.
Si los datos firmados han cambiado, la firma se marca como no válida. Hay un certificado de firma electrónica, prueba electrónica que confirma la identidad del firmante y vincula los datos de validación de la firma electrónica a esa persona. Las firmas electrónicas avanzadas pueden implementarse técnicamente, siguiendo los estándares para firmas digitales XAdES, PAdES, CAdES o ASiC Baseline Profile (Associated Signature Containers), especificados por ETSI.
3​

Creo que necesito firma xades xl

firma xades
las firmas xades se definen en el estándar etsi ts 101 903. Pueden descargarse una copia del estándar aquí.

Las firmas XAdES son una extensión de XMLDSig, por tanto una firma XAdES es un fichero XML. Para evitar problemas de codificación de caracteres y poder firmar archivos binarios, en el caso de que el documento se incluya en la firma siempre estará codificado en base64.

Arangí implementa 3 tipos de firma XAdES:

XAdES-BES: es el tipo de firma más simple.
XAdES-T: es una firma XAdES-BES a la que se añade un sello de tiempos.
XAdES-X-L: es una firma XAdES-T a la que se añade toda la información necesaria de validación de los certificados de firma y sus cadenas de certificación. De los 3 tipos de firma XAdES éste es el único que cumple con los criterios de firma longeva.
En un ciclo de vida típico de un modelo cliente-servidor, la firma realizada por el cliente sería XAdES-BES y, una vez llega al servidor se promocionaría a XAdES-T o XAdES-X-L. Esta acción se puede realizar porque para obtener los sellos de tiempo y la información de validación no es necesario que esté presente la clave privada de firma (que sólo se encuentra en el cliente). Si el cliente realiza la firma XAdES-X-L debe tener acceso a los servidores de sellos de tiempo y los servidores OCSP, lo que no siempre es posible.


Determinar el tipo de XAdES de una firma
En ocasiones se reciben ficheros con firmas y es necesario discernir de qué tipo de XAdES se trata. Para ello existe el método estático getXAdESObject(...) De la clase base XAdESSignature.

Import es.accv.arangi.base.XAdESSignature;
import es.accv.arangi.base.XAdESTSignature;

File file = new File ("c:/temp/xades.xml");
XAdESSignature signature = XAdESSignature.getXAdESObject(file);

//-- Si necesitamos que sea un XAdES-T
if (signature instanceof XAdESTSignature) {
        ...
}
Obtener una firma XAdES
Por la forma en la que se relacionan la firma y el documento se pueden dar 3 tipos de firmas XAdES:

Attached: aunque la firma y el documento se devuelven en un único fichero XML los dos se encuentran separados dentro del mismo y se firma únicamente la parte donde se encuentra el documento.
Detached: la firma y el documento se encuentran en ficheros diferentes.
Enveloped: al igual que el attached los dos elementos se encuentran en el mismo fichero, pero en este caso se firma todo el fichero.
Los métodos de firma de las clases XAdES permiten estas opciones:

signAttached: realiza una firma attached o enveloped.
SignDetached: realiza una firma detached.
Para cada uno de estos métodos se definen dos clases que servirán para pasarles las opciones con las que se quiere realizar la firma:

XAdESDetachedSignatureOptions: opciones para firmas detached:
digitalSignatureAlgorithm: nombre del algoritmo de firma.
TsaHashingAlgorithm: nombre del algoritmo de hashing utilizado para llamar a la TSA.
Dof: data object format definido como un objeto de la clase XAdESDataObjectFormat.
ClaimedRoles: array de roles que se incluirán en la firma.
PolicyIdentifier: policy identifier para realizar firmas EPES.
ProductionPlace: lugar de realización de la firma.
XAdESAttachedSignatureOptions: opciones para firmas attached. Se pueden incluir las mismas opciones que para los detached además de ésta:
nodeToSign: nodo que se firmará. Dependiendo de la implementación que elijamos para este campo obtendremos firmas attached o enveloped.

SignatureParent: nodo bajo el que quedará el tag Signature con la firma.
KeyStoreManager manager = new KeyStoreManager (new File("c:/temp/uactivo951v_firma.p12"), "1234");
File fileTexto = new File ("c:/temp/documento.txt");
FileDocument documentoTexto = new FileDocument (fileTexto);
File fileXML = new File ("c:/temp/documento.xml");
FileDocument documentoXML = new FileDocument (fileXML);

//-- Genera una firma attached.
XAdESAttachedSignatureOptions optionsAttached = new XAdESAttachedSignatureOptions ();
XAdESBESSignature signature1 = XAdESBESSignature.signAttached(manager, documentoTexto, optionsAttached);

//-- Genera una firma attached dentro del archivo pasado como documento. Se firmará el tag con ID="titulo".
XAdESAttachedNodeToSignObject nodeToSign = new XAdESAttachedNodeToSignObject("titulo");
optionsAttached.setNodeToSign(nodeToSign);
XAdESBESSignature signature2 = XAdESBESSignature.signAttached(manager, documentoXML, optionsAttached);

//-- Genera una firma enveloped.
OptionsAttached.setNodeToSign(new XAdESAttachedNodeToSignEnveloped());
XAdESBESSignature signature3 = XAdESBESSignature.signAttached(manager, documentoXML, optionsAttached);

//-- Genera una firma detached que referencia al fichero en disco
XAdESDetachedSignatureOptions optionsDetached = new XAdESDetachedSignatureOptions ();
XAdESBESSignature signature4 = XAdESBESSignature.signDetached(manager, documentoTexto, fileTexto.getAbsolutePath(), optionsDetached);

//-- Genera una firma detached que referencia a "2011/04/29/certificados/CER-2584665.pdf"
XAdESBESSignature signature5 = XAdESBESSignature.signDetached(manager, documentoTexto, "2011/04/29/certificados/CER-2584665.pdf", optionsDetached);

//-- Genera una firma XAdES-T detached realizada con el algoritmo Sha256withrsa, donde el hash de los
//-- sellos de tiempo se realiza mediante el algoritmo sha-256, se indica que el documento es un xml,
//-- se firmo con los roles 'secretario' y 'administrativo', la firma sigue la política de e-factura
//-- y la firma se realizó en vinaròs (castellón)
optionsdetached.setDigitalSignatureAlgorithm(DigitalSignatureAlgorithm.SHA256_RSA);
optionsDetached.setTsaHashingAlgorithm(HashingAlgorithm.SHA256);
XAdESDataObjectFormat dof = new XAdESDataObjectFormat("un documento de prueba", null, "text/xml", null);
optionsDetached.setDof(dof);
optionsDetached.setClaimedRoles(new String[] { "secretario", "administrativo" });
ArangiXAdESPolicyIdentifier aspi = new ArangiXAdESPolicyId(new String(Util.loadFile(new File("politica_efactura_xades_namespace.xml")), "UTF-8"));
optionsDetached.setPolicyIdentifier(aspi);
optionsDetached.setProductionPlace(new ArangiXAdESProductionPlace("Vinaros", "Castellón", "12500", "ES"));
XAdESTSignature signature6 = XAdESTSignature.signDetached(manager, documentoTexto, fileTexto.getAbsolutePath(), optionsDetached);     

Para comprender mejor el segundo ejemplo puede ver el fichero documento.xml aquí. Del mismo modo puede descargar la firma resultante de aquí.

En el último ejemplo se incluye un fichero que contiene la política de e-factura. Puede descargarse el fichero aquí. El resultado de esta firma lo encontrará aquí.


Las firmas para XAdES-T y XAdES-X-L se implementan de la misma forma que para XAdES-BES. Lógicamente estas clases realizarán más acciones y el resultado será distinto.

La información de validación de las firmas XAdES-X-L se obtiene mediante lladadas a servidores OSCP. Por defecto si no se puede obtener esta información se producirá una excepción. Si se desea que, en caso de no poder obtener una respuesta ocsp, se incluya en la firma información de validación obtenida mediante crl se deberá realizar las llamadas con el flag 'allowcrlvalidation' a true.


XAdESBESSignature signature = XAdESBESSignature.signAttached(manager, documentoTexto, optionsAttached, true);
Hay que tener cuidado con esta opción porque una CRL puede llegar a ocupar varios megabytes, con lo que la firma obtenida puede llegar a ser de un tamaño considerable.

Una vez se ha obtenido la firma es muy sencillo guardarla con el método save() o pasarla a array de bytes con el método toByteArray().

Promocionar una firma XAdES
Para promocionar una firma XAdES existen los siguientes métodos:

XAdESTSignature.completeToXAdEST(XAdESBESSignature): promociona una firma XAdES-BES a XAdES-T.
XAdESXLSignature.completeToXAdESXL(XAdESBESSignature): promociona una firma XAdES-BES a XAdES-X-L.
XAdESXLSignature.completeToXAdESXL(XAdESTSignature): promociona una firma XAdES-T a XAdES-X-L.
En el caso de querer promocionar una firma detached será necesario usar el método equivalente que tiene como parámetro el documento firmado:

XAdESTSignature.completeToXAdEST(XAdESBESSignature, IDocument): promociona una firma XAdES-BES a XAdES-T.
XAdESXLSignature.completeToXAdESXL(XAdESBESSignature, IDocument): promociona una firma XAdES-BES a XAdES-X-L.
XAdESXLSignature.completeToXAdESXL(XAdESTSignature, IDocument): promociona una firma XAdES-T a XAdES-X-L.
Cofirmar en XAdES
Para realizar una cofirma en XAdES será necesario proporcionar al método los parámetros habituales para firmar, además de la firma a cofirmar. Normalmente no será necesario pasar al método el documento que originó la firma, ya que éste se puede obtener fácilmente en los XAdES attached y, en el caso de los detached, es posible obtenerlos a través de la referencia incluida en la primera firma. Si dicha referencia no es un fichero o una URL desde la que se pueda obtener el documento si será necesario pasarlo como parámetro al método.


Otra cuestión sobre la cofirma es que no se permite cofirmar un documento distinto al que originó la primera firma.

Los métodos para cofirmar tienen el siguiente aspecto:

coSign (ACCVDeviceManager): modificará el XAdES al que hace referencia el objeto añadiendo una nueva firma.
CoSign (ACCVDeviceManager , IDocument): funcionará igual que método anterior para el caso en que sea necesario pasar al método el documento que originó la primera firma.
Contrafirmar en XAdES
Arangí consta de dos métodos para generar contrafirmas:

counterSign (ACCVDeviceManager): modificará el XAdES al que hace referencia el objeto contrafirmando la última firma generada en el mismo.
CounterSign (ACCVDeviceManager , Certificate): funcionará igual que método anterior pero ahora podremos seleccionar la firma a contrafirmar. El certificado que pasamos como parámetro servirá para identificarla. El listado con los certificado usados para generar las firmas del XAdES los podemos obtener previamente mediante el método getCertificates() común a todas las clases XAdES.

XAdES-A
Las firmas XAdES-X-L presentan una única debilidad: al caducar el certificado de la Autoridad de Sellado de tiempos es imposible validar este certificado. El formato XAdES-A es un XAdES-X-L al que se añade un sello de tiempos (llamado de archivado) para toda la firma. Dicho sellado ha de producirse antes de que caduque el certificado de los sellos de tiempos de la firma.


Arangí no implementa una clase específica para el formato XAdES-A ya que no se realizan firmas en este formato, tal y como se ha comentado se firmará (o completará) en XAdES-X-L y sólo cuando quede poco tiempo para que caduque el certificado de la TSA se resellará la firma obteniéndose un XAdES-A. Así pues, un XAdES-A será tratado por la clase XAdESXLSignature. ÉSta dispone de dos métodos para trabajar con el formato XAdES-A:

getTimeStampCertificateExpiration(): Devuelve la fecha en la que caducará el certificado de la TSA de los sellos de tiempos.
En caso de que los sellos estén firmados por varias tsa se devolverá la fecha de caducidad del certificado de tsa más cercano a caducar. En el caso de que ya se haya resellado (las firmas sean XAdES-A) se devolverá la fecha de caducidad del certificado de TSA del último resellado.
AddArchiveTimeStamp(): Añade un sello de tiempos de archivado a todas las firmas incluidas en el fichero XAdES-X-L (convirtiéndolo, si no lo era ya, en un XAdES-A).

Categoría Programación y Tecnología
Subcategoría Programación Web
¿Cuál es el alcance del proyecto? Bug o cambio pequeño
¿Es un proyecto o una posición? Un proyecto
Actualmente tengo Tengo las especificaciones
Disponibilidad requerida Según se necesite
Roles necesarios Programador

Plazo de Entrega: 29 Junio, 2019

Habilidades necesarias

Otros proyectos publicados por A.