Signature multiple PDFBox donnant une signature Java invalide

Nov 26 2020

J'avais des exigences de flux de travail de signature multiple PDF. Dans ce pdf, il sera signé plusieurs fois sans modification du document, par exemple 2 personnes ou plus peuvent signer le même document. J'essaye d'ajouter les signatures en pdf deux fois mais après avoir signé la deuxième fois la première signature de pdf devient invalide. J'ai utilisé l'API Java PDFBox pour la création de signatures PDF.

Étapes de création PDF:

  1. Création de pdf en ajoutant des noms de champs de signature vides: [email protected] et [email protected] en utilisant l'original hello.pdf hors du nom de fichier hello_tag.
  2. Première signature en récupérant le champ de signature [email protected] à partir du fichier hello_tag.pdf, le nom du fichier est hello_signed.pdf exécuter le programme> SignAndIdentifySignatureFields.java
  3. Deuxième signature en récupérant le champ de signature [email protected] à partir du fichier hello_signed.pdf, le nom du fichier est hello_singed2.pdf exécuter le programme> Sign2.java

Dans la deuxième étape, le pdf est correctement signé, mais après la troisième étape, la version signée de la deuxième étape est invalidée et la signature de la troisième étape s'affiche correctement dans Acrobat Reader.

Veuillez trouver le code source Java de lien et un exemple de pdf pour référence. Lien Google Drive pdf_multi_signs_pdfbox_java

Toute aide serait appréciée.

Réponses

3 mkl Nov 27 2020 at 01:26

En bref, il y a un certain nombre de problèmes dans votre code. Le problème qui amène Adobe Reader à marquer votre première signature comme non valide après l'ajout d'une deuxième signature se trouve déjà dans votre étape de préparation TagPDFSignatureFieldsoù vous créez une entrée d'arborescence de pages en double non valide. Les autres problèmes devraient également être résolus, même si Adobe Reader ne se plaint pas actuellement.

Les enjeux en détail ...

Entrée de page en double

Dans TagPDFSignatureFieldsvotre méthode addEmptySignFieldcommence comme ceci:

private void addEmptySignField(String[] args) throws Exception, IOException {
    // Create a new document with an empty page.
    try (PDDocument document = PDDocument.load(new File(args[0]));)
    {
        PDPage page = document.getPage(0);
        document.addPage(page);

Ici, vous récupérez la première page documentet ajoutez immédiatement cette page à documentnouveau. Cela fait que le nœud d'arborescence racine des pages de votre fichier hello_tag.pdfressemble à ceci:

2 0 obj
<<
/Type /Pages
/Count 2
/Kids [6 0 R 6 0 R]
>>
endobj 

C'est à dire que l'arborescence des pages contient deux fois le même objet de page qu'Adobe Reader n'accepte pas mais répare sous le capot. Pour les documents signés, Adobe Reader met en garde à ce sujet de manière vague:

Et dans les versions actuelles (par exemple 2020.013.20066) Adobe Reader dans le fichier deux fois signé marque même la première signature comme cassée. Dans les versions antérieures (par exemple 2019.012.20040), il ne le faisait pas. C'est probablement un effet du durcissement du code de validation après la publication des Shadow Attacks.

En passant: si vous avez une situation dans laquelle la manipulation d'un document signé (remplissage de formulaire, signature à nouveau, ...) casse les anciennes signatures, vérifiez toujours également si le document original peut déjà avoir des problèmes. Le contrôle si les modifications appliquées à un document signé sont autorisées, sont assez sensibles aux erreurs qui autrement sont corrigées sous le capot et, par conséquent, invisibles.

Noms de champ partiels non valides

Vous utilisez des adresses e-mail comme noms de champ, [email protected]et [email protected]dans le cas de votre exemple:

signatureField.setPartialName("[email protected]");
...
signatureField1.setPartialName("[email protected]");

( TagPDFSignatureFieldsméthode addEmptySignField)

Ces noms de champs partiels ne sont pas valides, les noms de champs partiels ne doivent pas contenir de caractères de point («.»).

PDFBox dans les versions futures tentera d'empêcher cela, voir PDFBOX-5028 .

Définition des ressources par défaut et des apparences par défaut lors de la signature

Lors de la signature, vous définissez les ressources par défaut et l'apparence par défaut du dictionnaire AcroForm :

acroForm.setDefaultResources(resources);
...
acroForm.setDefaultAppearance(defaultAppearanceString);

( SignAndIdentifySignatureFieldset Sign2méthode addEmptySignField)

En soi, ce n'est pas une mauvaise chose, mais attention, si vous faites cela à un fichier précédemment signé qui a déjà de telles entrées et que vous les définissez sur des valeurs différentes qu'avant, cela peut invalider l'ancienne signature , voir le problème résolu ici .

Définition de la version PDF sans besoin

Vous essayez de modifier la version PDF revendiquée du document:

document.setVersion(1.0f);

( SignAndIdentifySignatureFieldsméthode addEmptySignField)

document.setVersion(2.0f);

( Sign2méthode addEmptySignField)

La première instruction est ignorée car le document lui-même nécessite déjà une version d'au moins 1.5, mais la deuxième instruction définit en effet la version PDF du document sur 2.0, ce qui peut causer des problèmes avec les lecteurs plus anciens.

...

Il y a probablement plus de problèmes. J'ai simplement repéré ces problèmes avant de reconnaître que la résolution du seul premier, l'entrée de page en double, suffisait pour guérir la première signature ...