pdfbox:尝试解密PDF

时间:2015-04-16 13:16:54

标签: java encryption pdfbox

关注this answer我尝试使用pdfbox解密pdf文档:

PDDocument pd = PDDocument.load(path);
if(pd.isEncrypted()){
    try {
        pd.decrypt("");
        pd.setAllSecurityToBeRemoved(true);
    } catch (Exception e) {
        throw new Exception("The document is encrypted, and we can't decrypt it.");
    }

这导致

Exception in thread "main" java.lang.NoClassDefFoundError: org/bouncycastle/jce/provider/BouncyCastleProvider
at org.apache.pdfbox.pdmodel.PDDocument.openProtection(PDDocument.java:1601)
at org.apache.pdfbox.pdmodel.PDDocument.decrypt(PDDocument.java:948)
...
Caused by: java.lang.ClassNotFoundException: org.bouncycastle.jce.provider.BouncyCastleProvider
...

路径是正确的,所以我不知道发生了什么。 此外,如果我看一下PDDocument.decrypt(String pw)方法,我会发现: 这将解密文档。仅出于兼容性原因提供此方法。用户应该使用新的安全层,尤其是openProtection方法。

这是什么意思?有人可以举例说明如何使用pdfbox正确解密pdf文档吗?

2 个答案:

答案 0 :(得分:10)

查看依赖关系列表: https://pdfbox.apache.org/1.8/dependencies.html

您需要使用bouncycastle库。

<dependency>
  <groupId>org.bouncycastle</groupId>
  <artifactId>bcprov-jdk15</artifactId>
  <version>1.44</version>
</dependency>
<dependency>
  <groupId>org.bouncycastle</groupId>
  <artifactId>bcmail-jdk15</artifactId>
  <version>1.44</version>
</dependency>

在当前版本(1.8.9)中确实不推荐使用decrypt()调用。使用

pd.openProtection(new StandardDecryptionMaterial(""));

代替。

其他建议:下载源代码包。您将找到许多可以帮助您进一步发展的示例。

答案 1 :(得分:7)

要使用openProtection方法,您必须提供DecryptionMaterial的实例。在您的密码保护的情况下,它将是StandardDecryptionMaterial(来自API):

PDDocument doc = PDDocument.load(in);  
StandardDecryptionMaterial dm = new   StandardDecryptionMaterial("password");
doc.openProtection(dm);

此外,您必须使用加密/签名来完善PDFBox的Bouncy Castle依赖项。请参阅https://pdfbox.apache.org/1.8/dependencies.html