Repository navigation
Firma Digital XAdES
SignatureService firma documentos XML con firma electrónica avanzada XAdES, usando la librería EU DSS (Digital Signature Services).
SignatureService signatureService = new SignatureService(
"/ruta/al/certificado.p12",
"contraseñaDelCertificado"
);
byte[] xmlBytes = xmlString.getBytes("UTF-8");
byte[] signedXml = signatureService.signXml(xmlBytes);
⚠️ SignatureServicesolo exponesignXml(byte[]). No existe un métodoverifySignature(...)en esta clase — si necesitas verificar una firma, tendrás que implementarlo aparte usando las APIs deeu.europa.esig.dssdirectamente (por ejemplo conSignedDocumentValidator), o abrir un issue si te interesa que se añada al SDK.
signXml(...) produce una firma:
-
Nivel:
XAdES_BASELINE_B -
Empaquetado:
ENVELOPED(la firma queda insertada dentro del propio XML) -
Algoritmo de resumen:
SHA256 - El certificado se carga como
Pkcs12SignatureToken(formato.p12/.pfx), usando la primera clave privada disponible en el almacén (token.getKeys().get(0)).
Depende del modo con el que se instanció AeatClient (quinto parámetro del constructor, verifactuMode):
-
Modo VERI*FACTU (
verifactuMode=true):sendInvoice()/sendAnnulment()no invocanSignatureServiceinternamente. El envío a la AEAT se realiza vía SOAP sobre TLS mutuo usando directamente el certificado.p12(verAeatClient.configureSSL()), que es el mecanismo de autenticación que exige el servicio web de la AEAT para VeriFactu. Al ser una remisión síncrona en tiempo real, esa propia comunicación ya aporta la garantía de integridad frente a la AEAT, por lo que la normativa (RD 1007/2023) no exige aquí firma XAdES explícita. -
Modo NO VERI*FACTU (
verifactuMode=false, Requerimiento):sendInvoice()/sendAnnulment()sí invocanSignatureServiceinternamente y de forma obligatoria. El registro se genera, se calcula/encadena su huella exactamente igual que en modo VERI*FACTU, se marshala a XML y se firma con XAdES (SignatureService.signXml) usando el mismo certificado.p12configurado enAeatClient, sin realizar ninguna llamada SOAP a la AEAT. El XML firmado se devuelve codificado en Base64 enresponse.get("signedXml"), y es ese documento — no un simple JSON con los campos parseados — el que debes conservar como registro legal, íntegro y accesible ante una posible inspección (ver Encadenamiento y hash para el resto de campos de la respuesta en este modo).
En ambos casos puedes seguir usando SignatureService de forma independiente si necesitas firmar XML por tu cuenta fuera del flujo de sendInvoice/sendAnnulment (por ejemplo, para archivar copias firmadas adicionales).
Ejemplo completo: SignatureExample.java.