我有一个用所有者和用户密码锁定的PDF文件。我没有所有者密码,但我有用户密码。
我正在使用iText来解密文件
那么我应该如何解密PDF文件。
public class Decrypt {
public static final String SRC = "D:\\GitCodeBase(Master)\\pdf\\src\\main\\resources\\encrypt\\abc.pdf";
public static final String DEST = "D:\\GitCodeBase(Master)\\pdf\\src\\main\\resources\\decrypt\\def.pdf";
public static void main(String[] args) throws Exception {
PdfReader.unethicalreading = true;
PdfReader reader = new PdfReader(SRC,"abc123".getBytes());
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(DEST));
stamper.close();
reader.close();
}
}
答案 0 :(得分:2)
使用您的代码和示例文件,遗憾的是我无法重现该问题:代码执行时不会抛出异常。
但它还没有做你想要的:结果文件仍然是加密的。因此,这里有一些信息。
如果您阅读Bruno's answer here到最后,您会在iText 5.3.5之前看到您的代码用于解密PDF文件。但同时,加密仍然存在。严格来说,确实更正确,毕竟代码无处要求iText放弃加密。
因此,在目前的iText 5版本中(我使用当前的5.5.12-SNAPSHOT维护版本),你需要做更多的事情,你必须愚弄iText认为PDF不是&加密,正如布鲁诺在答案中所说的那样。
不幸的是,您必须更改的PdfReader
成员变量不是public
。因此,你不能简单地设置它。
有问题的成员是protected
。因此,您可以通过派生自己的PdfReader
子类并使用其中的方法来进行更改来更改它。这已在Bruno的答案中得到证明,这里是非空用户密码的变体:
class MyReader extends PdfReader {
public MyReader(final String filename, final byte password[]) throws IOException {
super(filename, password);
}
public void decryptOnPurpose() {
encrypted = false;
}
}
public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
MyReader.unethicalreading = true;
MyReader reader = new MyReader(src, "abc123".getBytes());
reader.decryptOnPurpose();
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
stamper.close();
reader.close();
}
或者你也可以使用反射:
PdfReader.unethicalreading = true;
PdfReader reader = new PdfReader(inputStream, "abc123".getBytes());
Field encryptedField = PdfReader.class.getDeclaredField("encrypted");
encryptedField.setAccessible(true);
encryptedField.set(reader, false);
PdfStamper stamper = new PdfStamper(reader, outputStream);
stamper.close();
reader.close();
(DecryptUserOnly.java测试方法testDecryptAbc
)
PS:我知道这个答案几乎没有为Bruno's original answer添加任何内容。我没有试图将这个问题标记为该答案问题的重复,只是因为它已被关闭为非主题"并且因为那个答案中的许多链接已经变得陈旧。