3 votes

Le PDF crypté / verrouillé par PDFBox est toujours modifié par Adobe Reader lors de l'enregistrement.

Je travaille sur une implémentation où notre système génère un fichier PDF qu'un utilisateur peut télécharger. La clé de notre processus et de notre système est que ce fichier PDF ne doit pas être modifiable par l'utilisateur ou par un programme sur l'ordinateur de l'utilisateur (du moins, pas sans mauvaise intention) car le fichier peut être téléchargé sur le système plus tard où nous devons nous assurer que le fichier est dans son état d'origine en comparant sa valeur de hachage.

Nous pensions y être parvenus en désactivant d'abord toutes les autorisations (CanModify, CanAssembleDocument, etc.), puis en chiffrant le document à l'aide du mot de passe du propriétaire. Cela empêchait la modification du fichier par tous les lecteurs auxquels nous avions accès. Il s'avère maintenant que l'un de nos utilisateurs modifie un PDF dès qu'il ouvre le fichier dans Acrobat Reader et "enregistre sous" le document dans un nouveau fichier PDF. Nous ne pouvons pas reproduire ce phénomène avec la même version d'Acrobat Reader (2015.006.30497), mais lui le peut, à chaque fois.

La solution consistant à signer le document PDF n'est pas envisageable pour nous, du moins pas avec une ICP ou une signature visible par les utilisateurs dans leur lecteur. S'il existait une option de signature invisible, ce serait formidable, mais je ne sais pas comment.

Vous trouverez ci-dessous le code que nous utilisons pour verrouiller le PDF. À des fins de test, nous avons désactivé TOUTES les autorisations, mais en vain. Nous utilisons PDFBox 2.0.11.

Quelles sont les options possibles pour mieux verrouiller le fichier en cas de modification ?

    public static byte[] SealFile(byte[] pdfFile, String password) throws IOException
    {   PDDocument doc =PDDocument.load(pdfFile);
        ByteArrayOutputStream bos= new ByteArrayOutputStream();
        byte[] returnvalue =null;
        int keyLength = 256;

        AccessPermission ap = new AccessPermission();

        //Disable all
        ap.setCanModifyAnnotations(false);
        ap.setCanAssembleDocument(false); .
        ap.setCanFillInForm(false);
        ap.setCanModify(false);
        ap.setCanExtractContent(false);
        ap.setCanExtractForAccessibility(false);
        ap.setCanPrint(false);

        //The user password is empty ("") so user can read without password. The admin password is
        // set to lock/encrypt the document.
        StandardProtectionPolicy spp = new StandardProtectionPolicy(password, "", ap);
        spp.setEncryptionKeyLength(keyLength);
        spp.setPermissions(ap);
        doc.protect(spp);
        doc.save(bos);
        doc.close();
        bos.flush();
        return bos.toByteArray();
    }

Il en résulte des propriétés Adobe :

Adobe properties

Editer (solution) : \==========

Comme suggéré par @mkl, (tous les crédits à cette personne) nous avons pu résoudre le problème avec l'utilisation de l'indicateur appendOnly, qui fait partie de la fonctionnalité AcroForm. Il s'est avéré que l'indicateur signatureExists n'était pas nécessaire pour résoudre notre problème. (et après avoir lu les spécifications, il n'était pas applicable).

Voici la solution que nous avons mise en œuvre :

    /*
     *  This method is used to add the 'appendOnly flag' to the PDF document. This flag is part of
     *  the AcroForm functionality that instructs a PDF reader that the file is signed and should not be
     *  modified during the 'saved as' function. For full description see PDF specification PDF 32000-1:2008
     *  (https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf)
     *  paragraph 12.7.2 Interactive Form Dictionary
     */
    public static void addAcroFormSigFlags(PDDocument pdfDoc) {
        PDDocumentCatalog catalog = pdfDoc.getDocumentCatalog();
        PDAcroForm acroForm = catalog.getAcroForm();
        if (acroForm == null) {
            acroForm = new PDAcroForm(pdfDoc);
            catalog.setAcroForm(acroForm);

        }
        // AppendOnly:
        // If set, the document contains signatures that may be invalidated if the
        // file is saved (wirtten) in a way that alters its previous contents, as
        // opposed to an incremental update. Merely updating the file by appending
        // new information to the end of the previous version is safe (see h.7,
        // "Updating Example"). Conforming readers may use this flag to inform a
        // user requesting a full save that signatures will be invalidated and
        // require explicit confirmation before continuing with the operation
        acroForm.setAppendOnly(true);

        // SignatureExists: (Currently not used by us)
        // If set, the document contains at least one signature field. This flag
        // allows a conforming reader to enable user interface items (such as menu
        // items or pushbuttons) related to signature processing without having to
        // scan the entire document for the presence of signature fields.
//        acroForm.setSignaturesExist(true);

        // flag objects that changed (in case a 'saveIncremental' is done hereafter)
        catalog.getCOSObject().setNeedToBeUpdated(true);
        acroForm.getCOSObject().setNeedToBeUpdated(true);

    }

1voto

mkl Points 13928

Même si vous n'avez pas la possibilité de signer le document PDF, vous pouvez essayer de définir le paramètre AcroForm les drapeaux qui affirmer qu'une signature existe .

Cela devrait empêcher les programmes sensibles à ces drapeaux (comme Adobe Reader) d'appliquer des modifications au PDF, ou du moins ils devraient appliquer leurs modifications sous forme de mises à jour incrémentielles qui peuvent être annulées en tronquant le fichier à sa taille d'origine.

L'entrée des drapeaux en question est le SigFlags dans la rubrique AcroForm dictionnaire.

Position du bit - Nom - Signification

1 - SignaturesExist - Si cette option est activée, le document contient au moins un champ de signature. Cet indicateur permet à un processeur PDF interactif d'activer les éléments de l'interface utilisateur (tels que les éléments de menu ou les boutons-poussoirs) liés au traitement des signatures sans avoir à numériser l'ensemble du document pour vérifier la présence de champs de signature.

2 - AppendOnly - Si cette option est activée, le document contient des signatures qui peuvent être invalidées si le fichier est sauvegardé (écrit) d'une manière qui modifie son contenu précédent, par opposition à une mise à jour incrémentale. La simple mise à jour du fichier en ajoutant de nouvelles informations à la fin de la version précédente est sans danger (voir H.7, "Exemple de mise à jour"). Les processeurs PDF interactifs peuvent utiliser cet indicateur pour informer un utilisateur demandant un enregistrement complet que les signatures seront invalidées et qu'une confirmation explicite sera nécessaire avant de poursuivre l'opération.

(ISO 32000-2, Tableau 225 - Drapeaux de signature)

Vous devez donc définir le paramètre SigFlags dans la rubrique AcroForm dans le dictionnaire Catalogue a 3 . Il se peut que vous deviez créer le AcroForm dictionnaire pour commencer si votre PDF n'a pas encore de définition de formulaire

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X