PDFBox加密/锁定的PDF在“另存为”期间仍由Adobe Reader修改

JPas

我正在一个实现中,我们的系统生成一个PDF文件供用户下载。我们的流程和系统的关键在于,该PDF文件不应由用户或用户计算机上的程序修改(至少,并非没有恶意),因为该文件可以稍后上传到系统中,通过比较其哈希值,确保文件处于其原始状态。

我们认为我们是通过首先禁用所有权限(CanModify,CanAssembleDocument等),然后使用所有者的密码加密文档来实现的。这阻止了我们有权访问的所有读者对文件的修改。现在事实证明,我们的一位用户在Acrobat Reader中打开文件并将其“另存为”到新的pdf文件后立即对其进行了修改。我们无法使用相同的阅读器版本(2015.006.30497)复制此内容,但他每次都可以。

对我们而言,签名PDF文档不是一种选择,至少不能使用PKI或用户在阅读器中可以看到的任何可见签名。如果有某种不可见的签名选项,那会很好,但我不知道如何。

在用于锁定PDF的代码下方。出于测试目的,我们禁用了所有权限,但无济于事。我们正在使用PDFBox 2.0.11。

有什么建议可以更好地锁定文件以进行修改吗?

    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();
    }

这将产生Adobe属性:

Adobe属性

编辑(解决方案): ==========

正如@mkl所建议的(此人的全部功劳),我们能够通过使用appendOnly标志来解决该问题,该标志是AcroForm功能的一部分。事实证明,解决我们的问题不需要signatureExists标志。(并且在阅读了规格之后,不适用)

以下是我们实施的解决方案:

    /*
     *  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);

    }
mkl

即使实际上不签署PDF文档,也可以尝试设置声称存在签名AcroForm标志

这应防止对这些标志敏感的程序(如Adobe Reader)将更改应用于PDF,或者至少应将其更改作为增量更新应用,可以通过将文件截短为原始大小来撤消这些更改。

有问题的标志条目是AcroForm词典中SigFlags条目

位位置名称—含义

1SignaturesExist(签名存在) —如果设置,则文档至少包含一个签名字段。该标志允许交互式PDF处理器启用与签名处理相关的用户界面项(例如菜单项或按钮),而不必扫描整个文档是否存在签名域。

2仅附加—如果设置,则文档包含签名,如果以更改其先前内容(而不是增量更新)的方式保存(写入)文件,则该签名可能无效。通过在新版本的末尾附加新信息来仅更新文件是安全的(请参阅H.7,“更新示例”)。交互式PDF处理器可以使用此标志来通知请求完全保存的用户签名将无效,并需要在继续操作之前进行明确确认。

(ISO 32000-2,表225-签名标志)

因此,你应该设置SigFlags在入门AcroForm字典中的目录,以3如果您的PDF尚无表单定义,则可能必须先创建AcroForm字典。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何停止Adobe Reader修改pdf

来自分类Dev

保存PDF表单时,如何阻止Adobe Reader询问“另存为”(即仅允许“保存”)?

来自分类Dev

在Adobe Reader DC中禁用新的另存为弹出窗口

来自分类Dev

Adobe Acrobat(不是Reader)中有哪些命令行选项可用于修改文档(转换,合并等)?

来自分类Dev

朱莉娅:如何修改已另存为二进制文件的矩阵的列?

来自分类Dev

在Adobe Acrobat中,“另存为”>“减小大小PDF”与“另存为”>“优化的PDF”之间有什么区别?

来自分类Dev

读取文本文件,在特定位置进行修改,然后另存为python中的新文件

来自分类Dev

动态将段落另存为PDF?

来自分类Dev

在景观中另存为PDF

来自分类Dev

Applescript Excel 2016另存为PDF

来自分类Dev

另存为PDF PHP页面

来自分类Dev

将油量图另存为PDF

来自分类Dev

将pdf文件另存为blob

来自分类Dev

Excel工作簿另存为.pdf

来自分类Dev

无法卸载Adobe Reader

来自分类Dev

无法打开Adobe Reader

来自分类Dev

无法卸载 Adobe Reader

来自分类Dev

Adobe PDF Reader控件axAcroPDF的文档

来自分类Dev

Adobe PDF Reader控件axAcroPDF的文档

来自分类Dev

当将JFileChooser与PDFBox一起使用时,该文件不会另存为pdf,但会以扩展名保存

来自分类Dev

如何打开另存为对话框并另存为PDF

来自分类Dev

将excel另存为pdf,将文件名另存为变量值

来自分类Dev

模拟另存为

来自分类Dev

边缘另存为

来自分类Dev

使用Adobe Reader全屏放大

来自分类Dev

如何将网页另存为PDF?

来自分类Dev

通过Excel将pptx另存为pdf

来自分类Dev

使用OpenXML将PowerPoint演示文稿另存为PDF

来自分类Dev

在服务器上将jasper报告另存为pdf

Related 相关文章

热门标签

归档