CEF eSignature Building Block "Hello World"

The CEF eSignature building block is a powerful tool but can be complex for smaller agencies. This series offers practical samples for Java developers to start with eIDAS-compliant digital signatures.

3 Oct
,
2020
2 May
,
2025
# min read
Digital signature process with eID Easy platform interface on a computer screen.

The CEF eSignature building block is a powerful toolkit for implementing digital signatures in line with the eIDAS regulation. However, getting started can be daunting due to the complexity of the components involved. As a result, many small development agencies shy away from projects that require qualified electronic signatures.

On the other end of the spectrum, large companies with extensive resources such as Nowina (developer of DSS and the EU reference implementation, based in Luxembourg) and Nortal (a seasoned implementer from Estonia) offer professional services in this domain.

This post is the first in a series focused on helping experienced Java developers kick-start their journey into electronic signature development in Europe—without spending weeks navigating the ecosystem.

Useful Resources

Sample Source Code: GitHub – CEF eSignature Samples

DSS Library Source Code: GitHub – DSS Components

Documentation: DSS Documentation

Demo Webapp: Signature Validation Demo

Tech Stack

In this guide, we’ll use:

  • Spring Boot
  • Maven
  • DSS (Digital Signature Services) Library

Our first goal is to sign a PDF using a .p12 key file with PAdES Baseline-B level.

Step 1: Add DSS Dependencies to pom.xml

Start by defining the DSS version and repository:

<properties>
    <java.version>14</java.version>
    <dss.groupId>eu.europa.ec.joinup.sd-dss</dss.groupId>
    <dss.version>5.7</dss.version>
</properties>

<repositories>
    <repository>
        <id>cefdigital</id>
        <url>https://ec.europa.eu/cefdigital/artifact/content/repositories/esignaturedss/</url>
    </repository>
</repositories>

Then include the necessary DSS modules for PAdES signing:

<dependencies>
    <dependency>
        <groupId>${dss.groupId}</groupId>
        <artifactId>dss-enumerations</artifactId>
        <version>${dss.version}</version>
    </dependency>
    <dependency>
        <groupId>${dss.groupId}</groupId>
        <artifactId>dss-service</artifactId>
        <version>${dss.version}</version>
    </dependency>
    <dependency>
        <groupId>${dss.groupId}</groupId>
        <artifactId>dss-pades</artifactId>
        <version>${dss.version}</version>
    </dependency>
    <dependency>
        <groupId>${dss.groupId}</groupId>
        <artifactId>dss-pades-pdfbox</artifactId>
        <version>${dss.version}</version>
    </dependency>
    <dependency>
        <groupId>${dss.groupId}</groupId>
        <artifactId>dss-token</artifactId>
        <version>${dss.version}</version>
    </dependency>
</dependencies>

Step 2: Signing a PDF with a .p12 File

Create a Spring Boot controller or service with the following logic:

Part 1: Prepare Signature Data

DSSDocument toSignDocument = new FileDocument("src/main/resources/test.pdf");
Pkcs12SignatureToken signingToken = new Pkcs12SignatureToken(
    "src/main/resources/teststore.p12",
    new KeyStore.PasswordProtection("123456".toCharArray())
);

DSSPrivateKeyEntry privateKey = signingToken.getKeys().get(0);
CertificateToken signerCert = privateKey.getCertificate();

PAdESSignatureParameters parameters = new PAdESSignatureParameters();
parameters.setSignatureLevel(SignatureLevel.PAdES_BASELINE_B);
parameters.setSigningCertificate(signerCert);

CommonCertificateVerifier certificateVerifier = new CommonCertificateVerifier();
PAdESService service = new PAdESService(certificateVerifier);
ToBeSigned dataToSign = service.getDataToSign(toSignDocument, parameters);

Part 2: Sign and Attach

SignatureValue signatureValue = signingToken.sign(dataToSign, DigestAlgorithm.SHA256, privateKey);
DSSDocument signedFile = service.signDocument(toSignDocument, parameters, signatureValue);
InputStreamResource resource = new InputStreamResource(signedFile.openStream());

Validating the Signature

Once signed, test your output using the DSS WebApp. Note:

  • Format, certificate identification, and cryptographic checks should pass.
  • If using a self-signed certificate, expect a warning: NO_CERTIFICATE_CHAIN_FOUND. This is expected unless your certificate is issued by a trusted CA.

Example Validation Result Summary

  • Format Checking: ✅ Passed
  • Signature Integrity: ✅ Passed
  • Cryptographic Verification: ✅ Passed
  • Certificate Validation: ⚠️ Indeterminate (NO_CERTIFICATE_CHAIN_FOUND)

Even with this warning, the signature itself is structurally valid.

More latest articles

See all news
See all news