Adding certification / docMDP signature using openPDF

615 Views Asked by At

I just stumbled over the following code in openPDF while creating a docMDP:

private void addDocMDP(PdfDictionary crypto) {
    PdfDictionary reference = new PdfDictionary();
    PdfDictionary transformParams = new PdfDictionary();
    transformParams.put(PdfName.P, new PdfNumber(certificationLevel));
    transformParams.put(PdfName.V, new PdfName("1.2"));
    transformParams.put(PdfName.TYPE, PdfName.TRANSFORMPARAMS);
    reference.put(PdfName.TRANSFORMMETHOD, PdfName.DOCMDP);
    reference.put(PdfName.TYPE, PdfName.SIGREF);
    reference.put(PdfName.TRANSFORMPARAMS, transformParams);
    reference.put(new PdfName("DigestValue"), new PdfString("aa"));
    PdfArray loc = new PdfArray();
    loc.add(new PdfNumber(0));
    loc.add(new PdfNumber(0));
    reference.put(new PdfName("DigestLocation"), loc);
    reference.put(new PdfName("DigestMethod"), new PdfName("MD5"));
    reference.put(PdfName.DATA, writer.reader.getTrailer().get(PdfName.ROOT));
    PdfArray types = new PdfArray();
    types.add(reference);
    crypto.put(PdfName.REFERENCE, types);
  }

This will also be put into the PDF:

/Reference[<</DigestLocation[0 0] /TransformMethod/DocMDP /Type/SigRef /DigestMethod/MD5  
/DigestValue(aa) /TransformParams<</P 1/V/1.2/Type/TransformParams>>/Data 5 0 R>>]

I changed the DigestMethod to something newer and it did just work. Also the 'aa' looks quite static and to be honest like a dummy implementation. Any insights about what those values are? And why can they be changed without consequence? I compared it with its predecessor *text 5 but it is the same there...

2

There are 2 best solutions below

2
On BEST ANSWER

Your question essentially is not about OpenPDF in particular but about certain values in the DocMDP transform dictionary. Thus, my answer will not be focused on OpenPDF.

In PDF versions 1.5 and 1.6 so-called Object Digests were used in addition to the Byte Range Digests in signatures with transform methods. These digests were calculated recursively over a certain set of PDF objects depending on type and parameters of the transform in question.

The DigestMethod value is the hash algorithm to use in object digests.

In Adobe's PDF Reference 1.7 object digests were deprecated which was made really clear in the errata:

Screenshot from Errata

In ISO 32000-1 object digests were completely removed from the text (in some cases leaving text behind which is difficult to understand).

Thus, the values you are wondering about are deprecated and are not to be used for verification purposes anymore.

You also find the reason why iText uses dummy values in the same errata:

screenshot

Thus, Adobe Acrobat 7 and 8 required some values to be there. Nowadays there is no need for them anymore.


In this context you may be interested in the PDF issue 117 - the DigestMethod had erroneously become required in ISO 32000-2:2020 and this issue is about deprecating it.

0
On

So in openPDF we could adapt the method like this:

private void addDocMDP(PdfDictionary crypto) {
    PdfDictionary reference = new PdfDictionary();
    PdfDictionary transformParams = new PdfDictionary();
    transformParams.put(PdfName.P, new PdfNumber(certificationLevel));
    transformParams.put(PdfName.V, new PdfName("1.2"));
    transformParams.put(PdfName.TYPE, PdfName.TRANSFORMPARAMS);
    reference.put(PdfName.TRANSFORMMETHOD, PdfName.DOCMDP);
    reference.put(PdfName.TYPE, PdfName.SIGREF);
    reference.put(PdfName.TRANSFORMPARAMS, transformParams);
    reference.put(PdfName.DATA, writer.reader.getTrailer().get(PdfName.ROOT));
    PdfArray types = new PdfArray();
    types.add(reference);
    crypto.put(PdfName.REFERENCE, types);
}

I tried and tested it and there are no complaints from *dobe reader...