Skip to content

Instantly share code, notes, and snippets.

@JohnnyJosep
Last active October 8, 2022 09:53
Show Gist options
  • Save JohnnyJosep/29cd545db3d0b7abd23279b56d4db194 to your computer and use it in GitHub Desktop.
Save JohnnyJosep/29cd545db3d0b7abd23279b56d4db194 to your computer and use it in GitHub Desktop.
Sample usage XAdES4j
package com.zertifika.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.security.KeyStore;
import javax.xml.parsers.DocumentBuilder;
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 org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import xades4j.algorithms.EnvelopedSignatureTransform;
import xades4j.production.DataObjectReference;
import xades4j.production.SignedDataObjects;
import xades4j.production.XadesBesSigningProfile;
import xades4j.production.XadesSigner;
import xades4j.production.XadesTSigningProfile;
import xades4j.properties.DataObjectDesc;
import xades4j.providers.CertificateValidationProvider;
import xades4j.providers.KeyingDataProvider;
import xades4j.providers.impl.AuthenticatedTimeStampTokenProvider;
import xades4j.providers.impl.DefaultMessageDigestProvider;
import xades4j.providers.impl.FileSystemKeyStoreKeyingDataProvider;
import xades4j.providers.impl.PKIXCertificateValidationProvider;
import xades4j.providers.impl.TSAHttpAuthenticationData;
import xades4j.utils.DOMHelper;
import xades4j.utils.FileSystemDirectoryCertStore;
import xades4j.verification.XadesVerificationProfile;
/**
*
* @author Joan Josep Escandell
*/
public class Main {
private static final String CERT_FOLDER = "C:/Certs/";
private static final String CERT = "mycert.pfx";
private static final String KEY_STORE = "KeyStorage";
private static final String PASS = "Password"; //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:/Test/sign-verify/signed-bes.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:/Test/sign-verify/document.xml";
private static final String DOCSIGNED = "C:/Test/sign-verify/signed.bes.xml";
public static void main(String[] args) throws Exception {
System.out.println("______________________");
System.out.println("\tSign");
System.out.println("______________________");
signBes();
System.out.println("______________________");
System.out.println("\tVerify");
System.out.println("______________________");
verifyBes();
}
private static void signBes() 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);
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);
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(SIGNED));
transformer.transform(source, result);
}
private static void signTBes() throws Exception {
Document doc = DocumentBuilderFactory
.newInstance()
.newDocumentBuilder()
.parse(new File(UNSIGNED));
Element elem = doc.getDocumentElement();
DOMHelper.useIdAsXmlId(elem);
KeyingDataProvider kdp = new FileSystemKeyStoreKeyingDataProvider(
"pkcs12",
CERT_FOLDER + CERT,
new FirstCertificateSelector(),
new DirectPasswordProvider(PASS),
new DirectPasswordProvider(PASS),
true);
DataObjectDesc obj = new DataObjectReference("#" + elem.getAttribute("Id"))
.withTransform(new EnvelopedSignatureTransform());
SignedDataObjects dataObjs = new SignedDataObjects().withSignedDataObject(obj);
XadesSigner signer = new XadesTSigningProfile(kdp)
.withTimeStampTokenProvider(
new AuthenticatedTimeStampTokenProvider(
new DefaultMessageDigestProvider(),
new TSAHttpAuthenticationData(TSA_URL, TSA_USER, TSA_PASS)))
.newSigner();
signer.sign(dataObjs, elem);
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(SIGNEDT));
transformer.transform(source, result);
}
private static void verifyBes() throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new FileReader(SIGNED)));
DOMHelper.useIdAsXmlId(doc.getDocumentElement());
NodeList nl = doc.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "Signature");
FileSystemDirectoryCertStore certStore = new FileSystemDirectoryCertStore(CERT_FOLDER);
KeyStore ks;
try (FileInputStream fis = new FileInputStream(CERT_FOLDER + KEY_STORE)) {
ks = KeyStore.getInstance("jks");
ks.load(fis, PASS.toCharArray());
}
CertificateValidationProvider provider = new PKIXCertificateValidationProvider(
ks, false, certStore.getStore());
XadesVerificationProfile profile = new XadesVerificationProfile(provider);
Element sigElem = (Element) nl.item(0);
XAdESVerificationResult r = profile.newVerifier().verify(sigElem, null);
System.out.println("Signature form: " + r.getSignatureForm());
System.out.println("Algorithm URI: " + r.getSignatureAlgorithmUri());
System.out.println("Signed objects: " + r.getSignedDataObjects().size());
System.out.println("Qualifying properties: " + r.getQualifyingProperties().all().size());
for (QualifyingProperty qp : r.getQualifyingProperties().all()) {
if ("SigningCertificate".equals(qp.getName())) {
Collection<X509Certificate> certs = ((SigningCertificateProperty)qp).getsigningCertificateChain();
certs.forEach((cert) -> {
System.out.println("Issuer DN: " + cert.getIssuerDN());
});
}
else if ("SigningTime".equals(qp.getName())) {
System.out.println("Time: " + ((SigningTimeProperty)qp).getSigningTime().getTime().toString());
} else if ("SignatureTimeStamp".equals(qp.getName())) {
System.out.println("Time stamp: " + ((SignatureTimeStampProperty)qp).getTime().toString());
}else {
System.out.println("QP: " + qp.getName());
}
}
}
}
@WindowsNT
Copy link

Verification fails...

Exception in thread "main" xades4j.providers.CannotBuildCertificationPathException: Trust anchors KeyStore has no trusted certificate entries
at xades4j.providers.impl.PKIXCertificateValidationProvider.validate(PKIXCertificateValidationProvider.java:229)
at xades4j.verification.XadesVerifierImpl.verify(XadesVerifierImpl.java:182)
at xades4jc.Main.verifyBes(Main.java:184)
at xades4jc.Main.main(Main.java:71)
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:200)
at java.security.cert.PKIXParameters.(PKIXParameters.java:157)
at java.security.cert.PKIXBuilderParameters.(PKIXBuilderParameters.java:130)
at xades4j.providers.impl.PKIXCertificateValidationProvider.validate(PKIXCertificateValidationProvider.java:223)
... 3 more

@dantebarba
Copy link

These classes DirectPasswordProvider FirstCertificateSelector are not available in version 1.5.1. Which one are you using for this example to work?

@trebsoj
Copy link

trebsoj commented Apr 12, 2021

These classes DirectPasswordProvider FirstCertificateSelector are not available in version 1.5.1. Which one are you using for this example to work?

luisgoncalves/xades4j#122 (comment)

@jialvarez
Copy link

I just want to say thank you. It worked in the first chance.

@omeeerOne
Copy link

image
Hi, does anyone have this problem?

@M4NN3
Copy link

M4NN3 commented Sep 21, 2022

image

@Max7Python
Copy link

I get the error


Sign

Exception in thread "main" java.lang.NoClassDefFoundError: com/google/inject/Module
at xades4j.production.XadesSigningProfile.(XadesSigningProfile.java:90)
at xades4j.Firma.signBes(Firma.java:103)
at xades4j.Firma.main(Firma.java:68)
Caused by: java.lang.ClassNotFoundException: com.google.inject.Module
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 3 more

However, I add the guice-4.0.jar and issue remais the same.
any tip?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment