如何使用所有者密码解密PDF文档? [英] How can I decrypt a PDF document with the owner password?

查看:410
本文介绍了如何使用所有者密码解密PDF文档?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要能够从某些PDF文档中删除安全/加密,最好使用itextsharp库。以前这是可能的(如何通过使用c#?提供文件密码作为参数来解密pdf文件),但是最近的一个更改到库意味着解决方案不再有效。

I need to be able to remove the security/encryption from some PDF documents, preferably with the itextsharp library. This used to be possible (How to decrypt a pdf file by supplying password of the file as argument using c#?), but a more recent change to the library means that solution no longer works.

我知道这可以用Aspose PDF库(< a href =http://www.aspose.com/docs/display/pdfnet/Decrypt+PDF+File+using+Owner+Password =nofollow noreferrer>示例),但这似乎是一个昂贵的选择。

I know this can be done with the Aspose PDF library (example), but that appears to be an expensive option.

修改

所以这一切我以为我拥有我用于测试这个文件的文档的所有者密码。但实际上,我的密码是用户密码。 原因我认为这是所有者密码是因为它作为所有者密码和其他值不起作用。我相信用户密码代替用户密码的原因是, PdfReader.unethicalreading 字段设置为 true (它是一个全局标志,恰好在代码中的其他地方设置)。

So all this time I thought I was in possession of the owner password for the document I was using to test this. But in fact the password I had was the user password. The reason I thought it was the owner password was because it worked as the owner password and other values did not work. I believe the reason the user password worked in place of the user password was the fact that the PdfReader.unethicalreading field was set to true (it's a global flag that happened to be set elsewhere in code).

推荐答案

为了测试代码加密一个PDF文件,我们需要一个加密的PDF样本。我们将使用 EncryptPdf 示例创建此类文件。

In order to test code to encrypt a PDF file, we need a sample PDF that is encrypted. We'll create such a file using the EncryptPdf example.

public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
    PdfReader reader = new PdfReader(src);
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
    stamper.setEncryption("Hello".getBytes(), "World".getBytes(),
        PdfWriter.ALLOW_PRINTING, PdfWriter.ENCRYPTION_AES_128 | PdfWriter.DO_NOT_ENCRYPT_METADATA);
    stamper.close();
}

使用此代码,我创建一个加密文件 hello_encrypted.pdf ,我将在第一个示例中使用演示如何解密文件。

With this code, I create an encrypted file hello_encrypted.pdf that I will use in the first example demonstrating how to decrypt a file.

您的原始问题听起来像如何使用所有者密码解密PDF文档?

Your original question sounds like "How can I decrypt a PDF document with the owner password?"

这很简单。 DecryptPdf 示例显示如何执行此操作:

That is easy. The DecryptPdf example shows you how to do this:

public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
    PdfReader reader = new PdfReader(src, "World".getBytes());
    System.out.println(new String(reader.computeUserPassword()));
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
    stamper.close();
    reader.close();
}

我们创建一个 PdfReader 传递所有者密码作为第二个参数的实例。如果我们想知道用户密码,我们可以使用 computeUserPassword()方法。我们是否要加密文件,比我们可以使用我们知道的所有者密码和我们计算的用户密码,并使用 setEncryption()方法重新引入安全性。

We create a PdfReader instance passing the owner password as the second parameter. If we want to know the user password, we can use the computeUserPassword() method. Should we want to encrypt the file, than we can use the owner password we know and the user password we computed and use the setEncryption() method to reintroduce security.

然而,由于我们没有这样做,所有的安全性被删除,这正是你想要的。这可以通过查看 hello.pdf 文档进行检查。

However, as we didn't do this, all security is removed, which is exactly what you wanted. This can be checked by looking at the hello.pdf document.

人们可以认为,你的问题属于不工作的问题,只能用对我有用的答案来回答。您可以投票结束您的问题,因为您没有提供可用于重现问题的代码示例,而任何人都可以提供证明您错误的代码示例。

One could argue that your question falls in the category of "It doesn't work" questions that can only be answered with an "it works for me" answer. One could vote to close your question because you didn't provide a code sample that can be use to reproduce the problem, whereas anyone can provide a code sample that proves you wrong.

幸运的是,我可以在两行之间阅读,所以我再举一个例子。

Fortunately, I can read between the lines, so I have made another example.

许多PDF是加密的,没有用户密码。他们可以由任何人打开,但加密是为了执行某些限制(例如,您可以查看文档,但不能打印)。在这种情况下,只有一个所有者密码,如 EncryptPdfWithoutUserPassword 示例:

Many PDFs are encrypted without a user password. They can be opened by anyone, but encryption is added to enforce certain restrictions (e.g. you can view the document, but you can not print it). In this case, there is only an owner password, as is shown in the EncryptPdfWithoutUserPassword example:

public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
    PdfReader reader = new PdfReader(src);
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
    stamper.setEncryption(null, "World".getBytes(),
        PdfWriter.ALLOW_PRINTING, PdfWriter.ENCRYPTION_AES_128 | PdfWriter.DO_NOT_ENCRYPT_METADATA);
    stamper.close();
    reader.close();
}

现在我们得到一个加密的PDF,但可以打开没有用户密码: hello_encrypted2.pdf

Now we get a PDF that is encrypted, but that can be opened without a user password: hello_encrypted2.pdf

如果我们想要操作PDF,我们仍然需要知道所有者的密码。如果我们没有通过密码,则iText将正确地抛出异常:

We still need to know the owner password if we want to manipulate the PDF. If we don't pass the password, then iText will rightfully throw an exception:

Exception in thread "main" com.itextpdf.text.exceptions.BadPasswordException: Bad user password
    at com.itextpdf.text.pdf.PdfReader.readPdf(PdfReader.java:681)
    at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:181)
    at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:230)
    at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:207)
    at sandbox.security.DecryptPdf.manipulatePdf(DecryptPdf.java:26)
    at sandbox.security.DecryptPdf.main(DecryptPdf.java:22)

但是,如果我们不记得所有者密码怎么办?如果PDF是由第三方生产的,我们不想尊重第三方的愿望呢?

But what if we don't remember that owner password? What if the PDF was produced by a third party and we do not want to respect the wishes of that third party?

在这种情况下,您可以刻意不道德地改变静态 unethicalreading 变量的值。这是在 DecryptPdf2 示例中完成的:

In that case, you can deliberately be unethical and change the value of the static unethicalreading variable. This is done in the DecryptPdf2 example:

public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
    PdfReader.unethicalreading = true;
    PdfReader reader = new PdfReader(src);
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
    stamper.close();
    reader.close();
}

如果使用用户加密文档,此示例将无法正常工作和所有者密码,在这种情况下,您必须传递至少一个密码,即所有者密码或用户密码(您只能使用用户访问PDF的事实密码是不道德阅读的副作用)。如果仅引入了一个所有者密码,iText不需要该拥有者的密码来操纵PDF,如果您更改非标准化标志。

This example will not work if the document was encrypted with a user and an owner password, in that case, you will have to pass at least one password, either the "owner password" or the "user password" (the fact that you have access to the PDF using only the "user" password is a side-effect of unethical reading). If only an owner password was introduced, iText does not need that owner password to manipulate the PDF if you change the unethicalreading flag.

但是:以前在iText中有一个bug,在这种情况下也删除了所有者的密码。这不是所期望的行为。在第一个 PdfDecrypt 示例中,我们看到我们可以检索用户密码(如果存在用户密码),但无法检索所有者密码。这是真的秘密。使用iText的旧版本,操作后,所有者密码已从文件中删除,并且所有者密码永久丢失。

However: there used to be a bug in iText that also removed the owner password(s) in this case. That is not the desired behavior. In the first PdfDecrypt example, we saw that we can retrieve the user password (if a user password was present), but there is no way to retrieve the owner password. It is truly secret. With the older versions of iText you refer to, the owner password was removed from the file after manipulating it, and that owner password was lost for eternity.

我已经修复了错误和修复在版本5.3.5。结果,所有者密码现在被保留。您可以查看 hello2.pdf ,这是我们的文件以不道德的方式解密。 (如果有一个所有者和一个用户密码,两者都被保留。)

I have fixed this bug and the fix is in release 5.3.5. As a result, the owner password is now preserved. You can check this by looking at hello2.pdf, which is the file we decrypted in an "unethical" way. (If there was an owner and a user password, both are preserved.)

根据这项研究,我假设您的问题不正确。你打算问:如何解密一个PDF文件,而不用所有者密码?或者如何使用用户密码解密PDF?

Based on this research, I am making the assumption that your question is incorrect. You meant to ask: "How can I decrypt a PDF document without the owner password?" or "How can I decrypt a PDF with the user password?"

>我曾经修复过的错误。我们不会恢复旧版iText版本的(错误)行为,但这并不意味着您无法实现所需的功能。您只需愚弄iText,认为PDF未加密。

It doesn't make sense to unfix a bug that I once fixed. We will not restore the (wrong) behavior of the old iText versions, but that doesn't mean that you can't achieve what you want. You'll only have to fool iText into thinking that the PDF wasn't encrypted.

这显示在 DecryptPdf3 示例:

class MyReader extends PdfReader {
    public MyReader(String filename) throws IOException {
        super(filename);
    }
    public void decryptOnPurpose() {
        encrypted = false;
    }
}
public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
    MyReader.unethicalreading = true;
    MyReader reader = new MyReader(src);
    reader.decryptOnPurpose();
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
    stamper.close();
    reader.close();
}

而不是 PdfReader 我们现在使用 PdfReader 的自定义子类。我已经命名为 MyReader ,并且我添加了一个额外的方法,允许我将加密的变量设置为 false

Instead of PdfReader, we are now using a custom subclass of PdfReader. I have named it MyReader and I have added an extra method that allows me to set the encrypted variable to false.

我仍然需要使用 unethicalreading MyReader 实例,我必须愚弄这个读者,认为原始文件没有通过使用 decryptOnPurpose()方法。

I still need to use unethicalreading and right after creating the MyReader instance, I have to fool this reader into thinking that the original file wasn't encrypted by using the decryptOnPurpose() method.

这将导致文件 hello3.pdf ,这是一个不再使用所有者密码加密的文件。只要您拥有用户密码,此示例甚至可以用于从用户和所有者密码加密的文件中删除所有密码。

This results in the file hello3.pdf which is a file that is no longer encrypted with an owner password. This example can even be used to remove all passwords from a file that is encrypted with a user and an owner password as long as you have the user password.

我将结束这个答案与评论回答你的话说Aspose不是免费的。你知道iText是免费软件,但你也应该知道,免费不是的免费的同义词。请阅读以下问题的答案以获取更多信息: iText Java库是免费还是有任何费用?

I'll conclude this answer with a comment in answer to your remark about Aspose not being free of charge. You know that iText is free software, but you should also know that free isn't a synonym of for free. Please read my answer to the following question for more info: Is iText Java library free of charge or have any fees to be paid?

这篇关于如何使用所有者密码解密PDF文档?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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