使用PDFBox保护PDF [英] Protecting PDF using PDFBox

查看:308
本文介绍了使用PDFBox保护PDF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的在为PDFBox的文档苦苦挣扎.对于这样一个受欢迎的图书馆,信息似乎在地面上薄了(对我来说!).

无论如何,我所遇到的问题与保护PDF有关.目前,我只想控制用户的访问权限.特别是我想防止用户修改PDF.

如果我省略了访问许可代码,那么一切都将正常运行.我正在从外部资源阅读PDF.然后,我将阅读并填充字段,并在保存新PDF之前添加一些图像.一切都很好.

当我添加以下代码来管理访问权限时,就会出现问题:

/* Secure the PDF so that it cannot be edited */
try {
    String ownerPassword = "DSTE$gewRges43";
    String userPassword = "";

    AccessPermission ap = new AccessPermission();
    ap.setCanModify(false);

    StandardProtectionPolicy spp = new StandardProtectionPolicy(ownerPassword, userPassword, ap);
    pdf.protect(spp);
} catch (BadSecurityHandlerException ex) {
    Logger.getLogger(PDFManager.class.getName()).log(Level.SEVERE, null, ex);
}

当我添加此代码时,所有文本和图像都从传出的pdf中剥离.这些字段仍然存在于文档中,但是它们都是空的,并且所有原始PDF部分以及在代码中动态添加的文本和图像都消失了.

更新: 好的,据我所知,问题出在与表单字段有关的错误.我将尝试一种不带表单字段的其他方法,看看它能提供什么.

解决方案

我找到了解决此问题的方法.看起来,如果PDF来自外部来源,则PDF有时会受到保护或加密.

如果从外部来源加载PDF文档并添加保护措施时输出空白,则可能是在使用加密的文档.我有一个处理PDF文档的流处理系统.因此以下代码对我有用.如果您仅使用PDF输入,则可以将以下代码与您的流程集成.

public InputStream convertDocument(InputStream dataStream) throws Exception {
    // just acts as a pass through since already in pdf format
    PipedOutputStream os = new PipedOutputStream();
    PipedInputStream is = new PipedInputStream(os);

    System.setProperty("org.apache.pdfbox.baseParser.pushBackSize", "2024768"); //for large files

    PDDocument doc = PDDocument.load(dataStream, true);

    if (doc.isEncrypted()) { //remove the security before adding protections
        doc.decrypt("");
        doc.setAllSecurityToBeRemoved(true);
    }
    doc.save(os);
    doc.close();
    dataStream.close();
    os.close();
    return is;
}

现在将返回的InputStream用作您的安全应用程序;

   PipedOutputStream os = new PipedOutputStream();
   PipedInputStream is = new PipedInputStream(os);

   System.setProperty("org.apache.pdfbox.baseParser.pushBackSize", "2024768");
   InputStream dataStream = secureData.data();

   PDDocument doc = PDDocument.load(dataStream, true);
   AccessPermission ap = new AccessPermission();
   //add what ever perms you need blah blah...
   ap.setCanModify(false);
   ap.setCanExtractContent(false);
   ap.setCanPrint(false);
   ap.setCanPrintDegraded(false);
   ap.setReadOnly();

   StandardProtectionPolicy spp = new StandardProtectionPolicy(UUID.randomUUID().toString(), "", ap);

   doc.protect(spp);

   doc.save(os);
   doc.close();
   dataStream.close();
   os.close();

现在,这应该返回没有空白输出的正确文档!

技巧是先删除加密!

Im really struggling with the documentation for PDFBox. For such a popular library info seems to be a little thin on the ground (for me!).

Anyway the problem Im having relates to protecting the PDF. At the moment all I want is to control the access permissions of the users. specifically I want to prevent the user from being able to modify the PDF.

If I omit the access permission code everything works perfectly. I am reading in a PDF from an external resource. I am then reading and populating the fields, adding some images before saving the new PDF. That all works perfectly.

The problem comes when I add the following code to manage the access:

/* Secure the PDF so that it cannot be edited */
try {
    String ownerPassword = "DSTE$gewRges43";
    String userPassword = "";

    AccessPermission ap = new AccessPermission();
    ap.setCanModify(false);

    StandardProtectionPolicy spp = new StandardProtectionPolicy(ownerPassword, userPassword, ap);
    pdf.protect(spp);
} catch (BadSecurityHandlerException ex) {
    Logger.getLogger(PDFManager.class.getName()).log(Level.SEVERE, null, ex);
}

When I add this code, all the text and images are striped from the outgoing pdf. The fields are still present in the document but they are all empty and all the text and images that where part of the original PDF and that were added dynamically in the code are gone.

UPDATE: Ok, as best as I can tell the problem is coming from a bug relating to the form fields. I'm going to try a different approach without the form fields and see what it gives.

解决方案

I found the solution to this problem. It would appear that if the PDF comes from an external source, sometimes the PDF is protected or encrypted.

If you get a blank output when loading up a PDF document from an external source and add protections you are probably working with an encrypted document. I have a stream processing system working on PDF documents. So the following code works for me. If you are just working with PDF inputs then you could integrate the below code with your flow.

public InputStream convertDocument(InputStream dataStream) throws Exception {
    // just acts as a pass through since already in pdf format
    PipedOutputStream os = new PipedOutputStream();
    PipedInputStream is = new PipedInputStream(os);

    System.setProperty("org.apache.pdfbox.baseParser.pushBackSize", "2024768"); //for large files

    PDDocument doc = PDDocument.load(dataStream, true);

    if (doc.isEncrypted()) { //remove the security before adding protections
        doc.decrypt("");
        doc.setAllSecurityToBeRemoved(true);
    }
    doc.save(os);
    doc.close();
    dataStream.close();
    os.close();
    return is;
}

Now take that returned InputStream and use it for your security application;

   PipedOutputStream os = new PipedOutputStream();
   PipedInputStream is = new PipedInputStream(os);

   System.setProperty("org.apache.pdfbox.baseParser.pushBackSize", "2024768");
   InputStream dataStream = secureData.data();

   PDDocument doc = PDDocument.load(dataStream, true);
   AccessPermission ap = new AccessPermission();
   //add what ever perms you need blah blah...
   ap.setCanModify(false);
   ap.setCanExtractContent(false);
   ap.setCanPrint(false);
   ap.setCanPrintDegraded(false);
   ap.setReadOnly();

   StandardProtectionPolicy spp = new StandardProtectionPolicy(UUID.randomUUID().toString(), "", ap);

   doc.protect(spp);

   doc.save(os);
   doc.close();
   dataStream.close();
   os.close();

Now this should return a proper document with no blank output!

Trick is to remove encryption first!

这篇关于使用PDFBox保护PDF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆