Las clases que implementan los tipos de firma se encuentran en es.accv.arangi.signature.
Los tipos de firma implementados son:
Todas las clases contienen métodos para firmar, validar y obtener información de la firma.
Como ejemplo de utilización de estos métodos se usará la firma CMS.
La firma supone llamar al método estático sign de la clase correspondiente. Como resultado se obtiene un objeto de la clase.
KeyStoreManager [] managers = new KeyStoreManager [1]; managers[0] = new KeyStoreManager (new File("c:/temp/uactivo951v_firma.p12"), "1234"); InputStreamDocument document = new InputStreamDocument (new FileInputStream ("c:/temp/documento.txt")); CMSSignature signature = CMSSignature.sign(managers, document); signature.save(new File ("c:/temp/firma.cms"));
En primer lugar se obtiene un manager de dispositivo (en el ejemplo se trata de un fichero PKCS#12). Si se pasan varios managers de dispositivo se obtendrá una firma múltiple.
Después hay que obtener el documento a firmar (en el ejemplo es un fichero de disco). Finalmente la llamada a sign devuelve un objero CMSSignature que puede ser guardado en disco.
La validación de una firma supone realizar dos acciones:
Se ofrecen dos métodos para realizar la primera validación:
Y cuatro métodos que realizan la validación completa (validación de la integridad y de la validez del certificado):
Puede ver cómo se utilizan los servicios de validación en el apartado Validación de certificados.
Ejemplo:
CMSSignature signature = new CMSSignature (ClassLoader.getSystemResourceAsStream("signature/signature.cms")); ValidationResult[] isValidSignatures = signature.isValidSignatureOnly(); ValidationResult[] isValidSignaturesCertificates = signature.isValid(); for(int i=0;i<isValidSignaturesCertificates.length;i++) { System.out.println(i + ". Firma valida: " + isValidSignaturesCertificates[i].isValid()); System.out.println(i + ". Resultado validación: " + isValidSignaturesCertificates[i].getResult()); if (isValidSignaturesCertificates[i].getResult() == ValidationResult.RESULT_CERTIFICATE_REVOKED) { System.out.println(i + ". El certificado de la firma está revocado"); } } CertificateValidationService servicio1 = ... List<CertificateValidationService> lServicios = new ArrayList<CertificateValidationService>(); lServicios.add(servicio1); isValidSignaturesCertificates = signature.isValid(lServicios); for(int i=0;i<isValidSignaturesCertificates.length;i++) { System.out.println(i + ". Resultado validación: " + isValidSignaturesCertificates[i].getResult()); if (isValidSignaturesCertificates[i].getResult() == ValidationResult.RESULT_CERTIFICATE_REVOKED) { System.out.println(i + ". El certificado de la firma está revocado"); } }
En el ejemplo puede verse como el resultado de la validación es un array de objetos es.accv.arangi.base.util.validation.ValidationResult de la librería base de Arangí, uno por cada firma contenida en el CMS. Para conocer el resultado de la validación podemos llamar al método getResult() que nos devolverá un entero indicando si la validación ha sido satisfactoria o la razón por la que no lo ha sido. El valor del entero viene descrito por las constantes de la clase:
Si sólo se quiere saber si la firma es válida o no se puede usar el método isValid() que devuelve un boolean. Además la clase ofrece métodos para obtener la fecha de la firma, el certificado firmante, el sello de tiempos y las respuestas OCSP asociadas.
La validación es exactamente igual para cualquier tipo de firma. Si en este ejemplo cambiasemos el tipo de firma para trabajar por ejemplo con XAdES-BES, el código para validar sería igualmente válido.
Lo normal es que al validar una firma se sepa el tipo de firma con el que se está trabajando. Sin embargo, en ciertas ocasiones, puede ser necesario trabajar con diferentes tipos de firma. Arangí disponde de varios métodos estáticos en la clase es.accv.arangi.base.signature.Signature que permiten realizar la validación de un fichero de firma sin que a priori se sepa de qué tipo de firma se trata:
Dadas dos firmas detached sobre el mismo documento, una es un CMS y otra un XAdES-BES, se podría hacer la validación de ambas de la siguiente forma:
IDocument document = new InputStreamDocument (ClassLoader.getSystemResourceAsStream("document/document.txt")); byte[] signature1 = Util.readStream (ClassLoader.getSystemResourceAsStream("signature/cms.cms")); byte[] signature2 = Util.readStream (ClassLoader.getSystemResourceAsStream("signature/xades-bes.xml")); List<CertificateValidationService> validationServices = ... CAList caList = ... ValidationResult[] isValidSignatures1 = Signature.validateSignature (document, signature1, validationServices, caList); ValidationResult[] isValidSignaturesCertificates2 = Signature.validateSignature(document, signature1); ValidationResult[] isValidSignatures2 = Signature.validateSignature (document, signature2, validationServices, caList); ValidationResult[] isValidSignaturesCertificates2 = Signature.validateSignature(document, signature2);