The problem I have is that I can sign the XML document, and during the
process, the signature validation is successful. However, once the file is
saved, the validation process throws an exception that says:
org.apache.xml.security.signature.MissingResourceFailureException: The
Reference for URI #SIGNED-PROPS-4ca238b2-09c4-4815-a513-f8ab4042cfed has no
XMLSignatureInput, but the reference exists, and the element with
id=SIGNED-PROPS-4ca238b2-09c4-4815-a513-f8ab4042cfed also exists in the
signed file.

I have a code to sign a xml inovice, here is part of it:
public static boolean Firmar(String nombre_archivo_a_firmar) {

        try {

            org.apache.xml.security.Init.init();

            String dirBase = "/dir_project/";
            String keyStoreFilePath = dirBase.concat("certificado.p12");
            String filePath = "/tmp/" + nombre_archivo_a_firmar + ".xml";
            String signedXmlFilePath = "/tmp/" + nombre_archivo_a_firmar +
"-firmada.xml";
            String privateKeyPassword = "passwordCertificado";
            String alias = "my name is the alias";

            // Cargar el documento XML
            DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            Document doc = dbf.newDocumentBuilder().parse(new
FileInputStream(filePath));

            // Establecer el prefijo para el namespace ds
            String dsPrefix = "ds";
            String dsNamespace = "http://www.w3.org/2000/09/xmldsig#";;
            ElementProxy.setDefaultPrefix(dsNamespace, dsPrefix);

            // Crear un elemento de firma
            XMLSignature sig = new XMLSignature(doc, null,
XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256);

            ...

            // Cargar el almacén de claves (KeyStore)
            KeyStore ks = KeyStore.getInstance("PKCS12");
            ks.load(new FileInputStream(keyStoreFilePath),
privateKeyPassword.toCharArray());
            PrivateKey privateKey = (PrivateKey) ks.getKey(alias,
privateKeyPassword.toCharArray());
            X509Certificate cert = (X509Certificate)
ks.getCertificate(alias);

            // Añadir las transformaciones necesarias
            Transforms transforms = new Transforms(doc);

transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
            sig.addDocument("", transforms,
MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA256);

            // Crear el elemento SignedProperties para XAdES-EPES
            Element qualifyingProperties = doc.createElementNS("
http://uri.etsi.org/01903/v1.3.2#";, "xades:QualifyingProperties");
            qualifyingProperties.setAttribute("Target", "#" + sig.getId());

            String signedPropsId = "SIGNED-PROPS-" + UUID.randomUUID();
            Element signedProperties = doc.createElementNS("
http://uri.etsi.org/01903/v1.3.2#";, "xades:SignedProperties");
            signedProperties.setAttributeNS(null,"Id", signedPropsId);
            signedProperties.setIdAttribute("Id", true);

            ...

            obj.appendChild(qualifyingProperties);

            // Añadir el ObjectContainer a la firma
            sig.appendObject(obj);
            System.out.println("object lenght: " + sig.getObjectLength());

            ...

            // Agregar la referencia al ObjectContainer en la firma
            sig.addDocument("#" + signedPropsId, null,
MessageDigestAlgorithm.ALGO_ID_DIGEST_SHA256);

            sig.addKeyInfo(cert);
            sig.addKeyInfo(cert.getPublicKey());

            // Añadir la firma al documento
            // Obtener el elemento de la segunda extensión y añadir la firma
            Element secondUBLExtensionContent =
findSecondUBLExtension(doc.getDocumentElement());
            if (secondUBLExtensionContent != null) {
                secondUBLExtensionContent.appendChild(sig.getElement());
            } else {
                System.out.println("No se pudo encontrar la segunda
extensión UBLExtension.");
                return false;
            }

            ...

            // Firmar el documento
            sig.sign(privateKey);


            // Guardar el documento firmado
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer trans = tf.newTransformer();
            trans.transform(new DOMSource(doc), new StreamResult(new
FileOutputStream(signedXmlFilePath)));


            // Validar la firma
            boolean isValid = sig.checkSignatureValue(cert.getPublicKey());
            System.out.println("FIRMA VÁLIDA " + isValid); //The result
here is TRUE - The signature is Valid


            // ----- Validation from signed xml file

            // Cargar el documento XML firmado para validación
            DocumentBuilderFactory dbfVal =
DocumentBuilderFactory.newInstance();
            dbfVal.setNamespaceAware(true);
            Document signedDoc = dbfVal.newDocumentBuilder().parse(new
FileInputStream(signedXmlFilePath));


            // Crear un objeto XMLSignature a partir del elemento Signature
            XMLSignature signature = new XMLSignature(signatureElement, "");

            // Obtener la clave pública del KeyInfo
            KeyInfo keyInfo = signature.getKeyInfo();
            if (keyInfo != null) {
                System.out.println("clave pública: " +
keyInfo.getPublicKey().toString());
                isValid =
signature.checkSignatureValue(keyInfo.getPublicKey());
                System.out.println("FIRMA VÁLIDA: " + isValid); //here
launch an exception, it says:
org.apache.xml.security.signature.MissingResourceFailureException: The
Reference for URI #SIGNED-PROPS-... has no XMLSignatureInput
                return isValid;
            } else {
                System.out.println("No se encontró KeyInfo en la firma.");
                return false;
            }

            //   return true;
        } catch (IOException | ParserConfigurationException | SAXException
| XMLSecurityException | KeyStoreException | NoSuchAlgorithmException |
CertificateEncodingException ex) {
            ex.printStackTrace();
        } catch (UnrecoverableKeyException | CertificateException ex) {
            ex.printStackTrace();
        } catch (TransformerConfigurationException ex) {
            Logger.getLogger(FirmaAS.class.getName()).log(Level.SEVERE,
null, ex);
        } catch (TransformerException ex) {
            Logger.getLogger(FirmaAS.class.getName()).log(Level.SEVERE,
null, ex);
        }
        return false;
    }

Thanks for your hel

Reply via email to