PDFBox加密和解密PDF文件

  • Post author:
  • Post category:其他


PDF常用的三种加密方式:

  1. 口令加密
  2. 证书加密
  3. Adobe LiveCycle Rights Management


口令加密:

作为第一代PDF安全加密方式,到现在也一直广泛应用。口令加密分为:用户密码(user password)、所有者密码(owner password)。

  • 用户密码:要求用户在打开文件时,需要输入密码
  • 所有者密码:打开PDF文件并进行阅读,并不需要所有者密码,只有更改权限设置或进行受限制操作时(打印,编辑和复制PDF中的内容),才需要输入所有者密码。

如果使用两种类型的密码保护PDF,则可以使用任一密码打开它。但是,只有所有者密码才允许用户更改受限制的功能。这种方式相对简单,加密算法和解密算法,在一些开源的PDF解析库(PDFBox)中,就可以很方便的获取到。


证书加密:

现在证书被大家广泛的应用,如:我们每天会访问大量的HTTPS网站,而这些网站的Web服务器正在使用基于证书的SSL加密来防止窃听和篡改。 在PDF文件中,我们也可以通过证书加密来确保PDF的安全。数字签名可确保收件人证明文件来自制作者,而证书加密可确保只有预期的收件人才能查看内容。

使用证书保护PDF时,可以指定收件人并为每个收件人或用户组定义文件访问级别。类似与口令加密的权限密码,可以进行权限限制,例如,允许一个组签名并填写表单,另一个组可以编辑文本或删除页面。您可以从可信任身份列表,磁盘上的文件,LDAP服务器或Windows证书存储区(仅限Windows)中选择证书。始终将您的证书包含在收件人列表中,以便以后可以打开该文档。

这种方式,稍微复杂一些,在一些开源的PDF解析库(PDFBox)中,可以获取到。


Adobe LiveCycle Rights Management

是一个基于服务器的安全系统,可以对PDF进行动态控制。Adobe LiveCycle Rights Management ES可以配置为与LDAP,ADS和其他企业系统一起运行。Adobe LiveCycle Rights Management ES 提供的策略存储在服务器上,可以从服务器刷新。用户连接到Adobe LiveCycle Rights Management ES以使用这些策略。

安全策略存储在运行Adobe LiveCycle Rights Management ES 的服务器上,但PDF不存储。在某些情况下,用户需要连接到服务器才能打开或继续使用应用了安全策略的PDF。

在本文中,我们将介绍PDFBox库如何使用密码加密保护PDF,以及如何使用PDFBox读取PDF,并移除加密的PDF的密码保护。

使用PDFBox加密PDF

PDFBox使用了2个重要的类来加密PDF文件: 为了使用PDFBox加密PDF,使用了两个类-


1- AccessPermission

–此类表示对文档的访问权限,其中包括以下权限:

  • 打印文件
  • 修改文件内容
  • 复制或提取文档内容
  • 添加或修改注释
  • 填写交互式表格字段
  • 提取文本和图形以方便视觉障碍人士使用
  • 组装文件
  • 打印质量下降


2- StandardProtectionPolicy

–此类表示要添加到文档中以基于密码的保护的保护策略。此类的构造方法将AccessPermission类对象,所有者密码和用户密码作为参数。

PDF加密所需的两个密码是: – 用户密码 –打开和查看具有受限权限的文件。 – 所有者密码 –拥有所有权限访问文件。

使用PDFBox Java程序加密的PDF

详细加密代码:

    public static void encrypt() throws InvalidPasswordException, IOException {

        String srcpath = "d:/t/pdf/security/a.pdf";
        String despath = "d:/t/pdf/security/a-1.pdf";
        String ownerPassWord = "123";
        String userPassWord = "456";
        File file = new File(srcpath);
        // long start = System.currentTimeMillis();
        PDDocument load = PDDocument.load(file);

        AccessPermission permissions = new AccessPermission();
        // 是否可以插入/删除/旋转页面
        permissions.setCanAssembleDocument(false);
        // 是否可以复制和提取内容
        permissions.setCanExtractContent(false);

        permissions.setCanExtractForAccessibility(false);
        // 设置用户是否可以填写交互式表单字段(包括签名字段)
        permissions.setCanFillInForm(false);
        // 设置用户是否可以修改文档
        permissions.setCanModify(false);
        // 设置用户是否可以添加或修改文本注释并填写交互式表单字段,如果canModify()返回true,则创建或修改交互式表单字段(包括签名字段)。
        permissions.setCanModifyAnnotations(false);
        // 设置用户是否可以打印。
        permissions.setCanPrint(false);
        // 设置用户是否可以降级格式打印文档
        permissions.setCanPrintDegraded(false);

        StandardProtectionPolicy p = new StandardProtectionPolicy(ownerPassWord, userPassWord, permissions);
        SecurityHandler sh = new StandardSecurityHandler(p);
        sh.prepareDocumentForEncryption(load);
        PDEncryption encryptionOptions = new PDEncryption();
        encryptionOptions.setSecurityHandler(sh);

        load.setEncryptionDictionary(encryptionOptions);
        load.save(despath);

    }

使用PDFBox Java程序打开加密的PDF

如果要打开使用PDFBox进行密码保护的PDF,则可以使用PDDocument类的load方法并传递解密所需的密码。


PDDocument document = PDDocument.load(new File(ENCRYPTED_PDF), OWNER_PASSWORD);

详细解密代码:

    public static void decrypt() throws InvalidPasswordException, IOException {
        String srcpath = "d:/t/pdf/security/a-1.pdf";
        String despath = "d:/t/pdf/security/a-3.pdf";
        String ownerPassWord = "123";

        File file = new File(srcpath);
        PDDocument load = PDDocument.load(file, ownerPassWord);
        load.setAllSecurityToBeRemoved(true);
        load.save(despath);
    }