I'm trying to sign a simple XML using Xades4J using this example, but I got this error:
Exception in thread "main" xades4j.XAdES4jXMLSigException:
Cannot resolve element with ID
at xades4j.production.SignerBES.sign(SignerBES.java:277)
at xades4j.production.SignerBES.sign(SignerBES.java:130)
at xmlSigner.Main.main(Main.java:63)
Caused by: org.apache.xml.security.signature.ReferenceNotInitializedException: Cannot resolve element with ID
Original Exception was org.apache.xml.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID
at org.apache.xml.security.signature.Reference.getContentsBeforeTransformation(Reference.java:437)
at org.apache.xml.security.signature.Reference.calculateDigest(Reference.java:722)
at org.apache.xml.security.signature.Reference.generateDigestValue(Reference.java:414)
at org.apache.xml.security.signature.Manifest.generateDigestValues(Manifest.java:205)
at org.apache.xml.security.signature.XMLSignature.sign(XMLSignature.java:628)
at xades4j.production.SignerBES.sign(SignerBES.java:273)
... 2 more
Caused by: org.apache.xml.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID at org.apache.xml.security.utils.resolver.implementations.ResolverFragment.engineResolveURI(ResolverFragment.java:81) at org.apache.xml.security.utils.resolver.ResourceResolver.resolve(ResourceResolver.java:288) at org.apache.xml.security.signature.Reference.getContentsBeforeTransformation(Reference.java:435) ... 7 more
My code is this
package xmlSigner;
import java.io.File;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import xades4j.algorithms.EnvelopedSignatureTransform;
import xades4j.production.DataObjectReference;
import xades4j.production.SignedDataObjects;
import xades4j.production.XadesBesSigningProfile;
import xades4j.production.XadesSigner;
import xades4j.properties.DataObjectDesc;
import xades4j.providers.KeyingDataProvider;
import xades4j.providers.impl.FileSystemKeyStoreKeyingDataProvider;
import xades4j.providers.impl.DirectPasswordProvider;
import xades4j.providers.impl.FirstCertificateSelector;
import xades4j.utils.DOMHelper;
public class Main {
private static final String CERT_FOLDER = "C:\\Users\\...";
private static final String CERT = "keystore.p12";
//private static final String KEY_STORE = "KeyStorage";
private static final String PASS = "mypass"; //the same in cert and keystorage
//private static final String TSA_URL = "http://XXX.XXX.XXX/ts.inx";
//private static final String TSA_USER = "XXXXXXXX";
//private static final String TSA_PASS = "XXXXXXXX";
//private static final String UNSIGNED = "C:/Test/sign-verify/unsigned.xml";
private static final String SIGNED = "C:\\Users\\...\\FLUSSO_A_signed.xml";
//private static final String SIGNEDT = "C:/Test/sign-verify/signed-t-bes.xml";
//private static final String VERIFY = "C:/Test/sign-verify/verify-bes.txt";
//private static final String VERIFYT = "C:/Test/sign-verify/verify-t-bes.txt";
private static final String DOCUMENT = "C:\\Users\\..\\FLUSSO_A.xml";
//private static final String DOCSIGNED = "C:/Test/sign-verify/signed.bes.xml";
public static void main(String[] args) throws Exception {
Document doc = DocumentBuilderFactory
.newInstance()
.newDocumentBuilder()
.parse(new File(DOCUMENT));
Element elem = doc.getDocumentElement();
DOMHelper.useIdAsXmlId(elem);
KeyingDataProvider kdp = new FileSystemKeyStoreKeyingDataProvider(
"pkcs12",
CERT_FOLDER + CERT,
new FirstCertificateSelector(),
new DirectPasswordProvider(PASS),
new DirectPasswordProvider(PASS),
true);
// here I tried also EManifest (the XML root tag) and name (since elem has a "name" attribute)
DataObjectDesc obj = new DataObjectReference("#" + elem.getAttribute("Id"))
.withTransform(new EnvelopedSignatureTransform());
SignedDataObjects dataObjs = new SignedDataObjects().withSignedDataObject(obj);
XadesSigner signer = new XadesBesSigningProfile(kdp).newSigner();
signer.sign(dataObjs, elem); // fails here
/*TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(SIGNED));
transformer.transform(source, result);*/
}
}
The XML is an example document for customs processes and can be found here.
Any advice would be greatly appreciated.
I found the solution. The root tag of my XML looks like this
adding the attribute to the tag (specifically
Id="test"
) solved the issue.Now my root tag looks like this