6

We 're trying to sign a PDF document using the CAdES method and the examples in dss-cookbook as a starting point using the latest version (4.6.RC1).

Following the example from SignPdfPadesBDetached.java, we have succesfully signed a PDF document using PAdES. However, since there is no example for CAdES, we tried adapting the above example to use CAdES, but it doesn't work. Specifically the generated PDF document has a size of only 7k instead of the expected 2.5MB and the following error is displayed when trying to open the PDF:
enter image description here
We assume the 7k is actually only the signature so that the actual document is not included. The settings we use are:

  • SignatureLevel.CAdES_BASELINE_B
  • SignaturePackaging.DETACHED
  • DigestAlgorithm.SHA256

And the relative's method code is currently this:

public static void signPdfWithCades(DSSDocument toSignDocument) {

    LOG.info("Signing PDF with CADES B");

    try {
        AbstractSignatureTokenConnection signingToken = new Pkcs12SignatureToken("password", KEYSTORE_PATH);
        DSSPrivateKeyEntry privateKey = signingToken.getKeys().get(0);

        // Preparing parameters for the CAdES signature
        CAdESSignatureParameters parameters = new CAdESSignatureParameters();
        // We choose the level of the signature (-B, -T, -LT, -LTA).
        parameters.setSignatureLevel(SignatureLevel.CAdES_BASELINE_B);
        // We choose the type of the signature packaging (ENVELOPING, DETACHED).
        parameters.setSignaturePackaging(SignaturePackaging.DETACHED);
        // We set the digest algorithm to use with the signature algorithm. You must use the
        // same parameter when you invoke the method sign on the token. The default value is
        // SHA256
        parameters.setDigestAlgorithm(DigestAlgorithm.SHA256);

        // We set the signing certificate
        parameters.setSigningCertificate(privateKey.getCertificate());
        // We set the certificate chain
        parameters.setCertificateChain(privateKey.getCertificateChain());

        // Create common certificate verifier
        CommonCertificateVerifier commonCertificateVerifier = new CommonCertificateVerifier();
        // Create PAdES xadesService for signature
        CAdESService service = new CAdESService(commonCertificateVerifier);

        // Get the SignedInfo segment that need to be signed.
        ToBeSigned dataToSign = service.getDataToSign(toSignDocument, parameters);

        // This function obtains the signature value for signed information using the
        // private key and specified algorithm
        DigestAlgorithm digestAlgorithm = parameters.getDigestAlgorithm();
        SignatureValue signatureValue = signingToken.sign(dataToSign, digestAlgorithm, privateKey);

        // We invoke the cadesService to sign the document with the signature value obtained in
        // the previous step.
        DSSDocument signedDocument = service.signDocument(toSignDocument, parameters, signatureValue);

        LOG.info("Signed PDF size = " + signedDocument.getBytes().length);

        //We use the DSSUtils to Save to file
        DSSUtils.saveToFile(signedDocument.openStream(), "target/signedPdfCadesBDetached.pdf");
    } catch (Exception e) {
        LOG.error(e.getMessage(), e);
    }
}

The corresponding method for signing with PAdES is similar to the above, adjusted to PAdES (that is, we there used PAdESSignatureParameters, SignatureLevel.PAdES_BASELINE_B and PAdESService) classes.

Please note that the SD-DSS project is not hosted in the Maven Central repository, so we had to make an explicit reference to it:

<repositories>
    <repository>
        <id>europa</id>
        <url>https://joinup.ec.europa.eu/nexus/content/groups/public/</url>
    </repository>
</repositories>

In addition, I believe we included all of the required/corresponding dependencies in our pom.xml:

<dependency>
    <groupId>eu.europa.ec.joinup.sd-dss</groupId>
    <artifactId>dss-token</artifactId>
    <version>4.6.RC1</version>
</dependency>
<dependency>
    <groupId>eu.europa.ec.joinup.sd-dss</groupId>
    <artifactId>dss-pades</artifactId>
    <version>4.6.RC1</version>
</dependency>
<dependency>
    <groupId>eu.europa.ec.joinup.sd-dss</groupId>
    <artifactId>dss-cades</artifactId>
    <version>4.6.RC1</version>
</dependency>
<dependency>
    <groupId>eu.europa.ec.joinup.sd-dss</groupId>
    <artifactId>dss-document</artifactId>
    <version>4.6.RC1</version>
</dependency>

Prior to this, we also gave a try to PDFBox, but the documentation wasn't so helpful, according to what we want to accomplish.

Any idea what is wrong here? Changing the packaging ENVELOPING makes no difference either. Is the method for signing with CAdES so different that the PAdES example should not be used as a guide?

usr-local-ΕΨΗΕΛΩΝ
  • 26,101
  • 30
  • 154
  • 305
teobais
  • 2,820
  • 1
  • 24
  • 36

1 Answers1

6

In general,

PAdES signatures are specifically profiled signatures embedded into a PDF. Thus, your PAdES signed PDF can be opened in Adobe Reader, and Adobe Reader can recognize the signature, verify it, and display the result of that in its signature panel.

CAdES signatures are specifically profiled signatures which either are in a separate file or which contain the signed data. Neither of these formats is recognized by Adobe Reader, in case of the separate file you can open the original PDF but the Reader does not see the signature, in case of the contained PDF the Reader either cannot open the file at all or (as the Reader ignores some leading and trailing extra bytes) considers the signature ignorable trash.

You only need a PDF aware library (like PDFBox) for PAdES signatures, for CAdES signatures the PDF is treated like generic data bytes.


In your case, therefore, i.e. for

  • SignatureLevel.CAdES_BASELINE
  • SignaturePackaging.DETACHED

your 7K indeed is the mere signature in a separate file and you have to keep or forward both the PDF and the signature, the PDF for viewing and the signature for verification.

Thus,

Specifically the generated PDF document has a size of only 7k instead of the expected 2.5MB ...

We assume the 7k is actually only the signature so that the actual document is not included.

Your assumption is correct, and also the behavior is correct. Yout expectations are the issue.


Some confusion might result from the facts that the signature container embedded into a PDF in case of a PAdES signature, when extracted, proves to be in CAdES format, that the matching PDF subfilter is called ETSI.CAdES.detached, and that (at least in the most recent draft at hand) the PDF 2.0 specification will treat the PAdES signatures in a section titled "12.8.3.4 CAdES signatures as used in PDF (PDF 2.0)".

Nonetheless, if you are talking about PAdES signatures, you are talking about ETSI AdES signatures integrated in PDFs. If you are talking about CAdES signatures, you are talking about ETSI AdES CMS signatures independant of a specific document format which may be detached from the signed data or which may wrap them.


According to your comments, in particular this one

Signing the PDF using ETSI.CAdES.DETACHED filter is the exact requirement

you in the end do not want to create a CAdES signature but instead a PAdES signature, more exactly you want to do so according to the Part 3: PAdES Enhanced - PAdES-BES and PAdES-EPES Profiles and not according to Part 2: PAdES Basic - Profile based on ISO 32000-1 which uses the subfilters adbe.pkcs7.detached and adbe.pkcs7.sha1.

(To get the requirement straight, that is the subfilter value, not the filter value.)

This is exactly what the dss cookbook examples SignPdfPadesB, SignPdfPadesBDetached, and SignPdfPadesBVisible should be all about:

  • they all in their JavaDoc class comment claim to show How to sign PDF Document with PAdES-BASELINE-B,
  • the cookbook asciidoc/dss-documentation.adoc for PAdES Baseline profiles refers to ETSI TS 103 172,
  • and that standard specifies:

    6 Requirements for B-Level Conformance

    This clause defines requirements that PAdES signatures claiming conformance to the B-Level have to fulfil.

    The current clause specifies compliance requirements for short-term electronic signatures. This clause actually profiles PAdES-BES (signatures that do not incorporate signature-policy-identifier) and PAdES-EPES (signatures that do incorporate signature-policy-identifier) signatures.

    (ETSI TS 103 172 V2.1.1 (2012-03))

Unfortunately I cannot now verify that the samples do what they claim as my eclipse dss projects are all red with problems.

If they do, though, it looks like you in the beginning already had what you wanted:

Following the example from SignPdfPadesBDetached.java, we have succesfully signed a PDF document using PAdES.

You may share a sample PDF signed with that example for analysis to be sure.

mkl
  • 90,588
  • 15
  • 125
  • 265
  • So, if I made it clear: going in the PAdES way, will result in a CAdES signature, which means that we should just go with the initially displayed on my question code, used for the PAdES example? – teobais Jan 06 '16 at 23:07
  • Foremost it is time to get your requirements straightened out. Initially you said you wanted to sign a PDF using CAdES but then were surprised the result was not recognized by Adobe Reader. To me this looks like conflicting requirements which have to be cleared up first. – mkl Jan 06 '16 at 23:18
  • I believe the requirements are clear enough: we want to sign a PDF using CAdES, but when trying this, we then cannot open the PDF itself, 'cause this is only the signature that we produced, as you also verified. So, two things come up here: the first one, after reading your answer is that we just have to sign it with PAdES, as this will be extracted as CAdES on PDF and second one is that we are currently missing some basic functionality in our code. For the second case, a code snippet would help us better understanding. – teobais Jan 06 '16 at 23:49
  • If you really want to sign the PDF using CAdES, then you do not expect to be able to open the signature in Adobe Reader. If you really want to sign the PDF using detached CAdES, then you do expect the signature to reside in a separate small file which you have to store or forward alongside the PDF. If you do not have these expectations, you do not want to sign using CAdES. – mkl Jan 07 '16 at 05:15
  • Signing the PDF using `ETSI.CAdES.DETACHED` filter is the exact requirement (as the question's souce code implies). Could you provide a sample implementation please? – teobais Jan 09 '16 at 10:05
  • *Signing the PDF using `ETSI.CAdES.DETACHED` filter is the exact requirement* - in that case it looks like you in the beginning already had what you wanted, cf. my edited answer. *(as the question's souce code implies).* - This remark is completely unnecessary because **A** that source implies everything but, and **B** you asked here because you did not believe the source to be correct. *Could you provide a sample implementation please?* - You already have it, cf. my edit. – mkl Jan 09 '16 at 12:23
  • Thank you for your fully explained answer, it includes details we weren't aware of. – teobais Jan 14 '16 at 21:17