How to sign xml with XAdES4j, and reference URI (#DatosEmision)?

1.6k Views Asked by At

I am using this code to try to sign an xml, with a signature xades-bes:

// open file
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
builder = factory.newDocumentBuilder();
Document doc1 = builder.parse(new File(xmlInPath));

Element elemToSign = doc1.getDocumentElement();
DOMHelper.useIdAsXmlId(elemToSign);

kp = new FileSystemKeyStoreKeyingDataProvider("pkcs12", keyPath, new 
FirstCertificateSelector(),
new DirectPasswordProvider(password), new 
DirectPasswordProvider(password), true);

DataObjectDesc obj = new 
DataObjectReference("#DatosEmision").withTransform(new 
EnvelopedSignatureTransform());
SignedDataObjects dataObjs = new 
SignedDataObjects().withSignedDataObject(obj);

XadesSigningProfile p = new XadesBesSigningProfile(kp);

XadesSigner signer = p.newSigner();

signer.sign(dataObjs, elemToSign);

this returns error referring to not finding the ID:

xades4j.XAdES4jXMLSigException: Cannot resolve element with ID DatosEmision
at xades4j.production.SignerBES.sign(SignerBES.java:277)
at xades4j.production.SignerBES.sign(SignerBES.java:130)
at xadessignergt.Signer.sign(Signer.java:63)
at xadessignergt.Cli.main(Cli.java:24)
   Caused by: org.apache.xml.security.signature.ReferenceNotInitializedException: 
   Cannot resolve element with ID DatosEmision

Thanks in advance for your helps

2

There are 2 best solutions below

0
On

That's right, the problem was root, I did solve that, but I'm still missing something else, the xml result is adding two "certdigest" to the "object" node, and you have to add only the first one, that is, the following one

<xades: Cert>
<xades: CertDigest>
<ds: DigestMethod Algorithm = "http://www.w3.org/2001/04/xmlenc#sha256" />
<ds: DigestValue> bCkfbDWoqt1XCDnbu0uunEXhNYQTgwmA3kvi69fnBKI = </ ds: DigestValue>
</ xades: CertDigest>
<xades: IssuerSerial>
<ds: X509IssuerName> c = GT, o = SAT, cn = FEL </ ds: X509IssuerName>
<ds: X509SerialNumber> 2184761958499123161 </ ds: X509SerialNumber>
</ xades: IssuerSerial>
</ xades: Cert>

shouldn't be.

I pass the code and the part of the signed xml where you see the object that I need to correct:

java code:

        XadesSigningProfile p = new 
XadesBesSigningProfile(kp);//.withBasicSignatureOptions(new 
BasicSignatureOptions().includeSigningCertificate(SigningCertificateMode.NONE));

        XadesSigner signer = p.newSigner();

        DataObjectDesc dataObjects = new DataObjectReference("#" + 
elemToSign.getAttribute("ID")).withTransform(new EnvelopedSignatureTransform()); 
        signer.sign(new SignedDataObjects(dataObjects), elemToSign2);    

        Transformer transformer = 
TransformerFactory.newInstance().newTransformer();
        Result output = new StreamResult(xmlOutPath);
        Source input = new DOMSource(doc1);

        transformer.transform(input, output);

signed xml:

ds:Object>
<xades:QualifyingProperties xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" 
xmlns:xades141="http://uri.etsi.org/01903/v1.4.1#" Target="#xmldsig- 
d404515d- 
303f-483f-a665-783618a354ce">
<xades:SignedProperties Id="xmldsig-d404515d-303f-483f-a665-783618a354ce- 
signedprops">
<xades:SignedSignatureProperties>
<xades:SigningTime>2019-12-04T08:23:24.757-06:00</xades:SigningTime>
<xades:SigningCertificate>
<xades:Cert>
<xades:CertDigest>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>jvQigb4Z3jwOpSU+snlj7p7vjERxAxRBWna5uAHob0s= 
</ds:DigestValue>
</xades:CertDigest>
<xades:IssuerSerial>
<ds:X509IssuerName>c=GT,o=SAT,cn=FEL</ds:X509IssuerName>
<ds:X509SerialNumber>8490687699557173471</ds:X509SerialNumber>
</xades:IssuerSerial>
</xades:Cert>
<xades:Cert>                /*this does not have to appear - begin*/
<xades:CertDigest>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>bCkfbDWoqt1XCDnbu0uunEXhNYQTgwmA3kvi69fnBKI= 
</ds:DigestValue>
</xades:CertDigest>
<xades:IssuerSerial>
<ds:X509IssuerName>c=GT,o=SAT,cn=FEL</ds:X509IssuerName>
<ds:X509SerialNumber>2184761958499123161</ds:X509SerialNumber>
</xades:IssuerSerial>
</xades:Cert>                /*this does not have to appear - end*/
</xades:SigningCertificate>
</xades:SignedSignatureProperties>
</xades:SignedProperties>
</xades:QualifyingProperties>
</ds:Object>

Thanks in advance for your helps

0
On

The includeSigningCertificate flag controls what is added into KeyInfo. This probbaly is a bit confusing, but for SigningCertificate the lib adds all the certificates returned by the KeyingDataProvider.

So, in your case, you should supply false in the last parameter of FileSystemKeyStoreKeyingDataProvider (your keystore probably has the two certificates of the path in the key entry).

http://luisgoncalves.github.io/xades4j/javadocs/1.5.0/reference/xades4j/providers/impl/FileSystemKeyStoreKeyingDataProvider.html