【发布时间】:2018-08-27 22:55:11
【问题描述】:
我正在使用 PDFBox 从表单中提取文本,并且我有一个未使用密码加密的 PDF,但 PDFBox 表示已加密。我怀疑某种 Adobe“功能”,因为当我打开它时,它会显示 (SECURED),而我没有遇到问题的其他 PDF 则没有。 isEncrypted() 返回true,因此尽管没有密码,但它似乎以某种方式受到保护。
我怀疑它没有正确解密,因为它能够提取表单的文本提示,但不能提取响应本身。在下面的代码中,它从示例 PDF 中提取 Address (Street Name and Number) 和 City,但不是它们之间的响应。
我使用的是 PDFBox 2.0,但我也尝试过 1.8。
我已经尝试了所有可以为 PDFBox 找到的解密方法,包括已弃用的方法(为什么不)。我得到的结果与根本不尝试解密的结果相同,只是地址和城市提示。
PDF 绝对是他们的噩梦,这个 PDF 很可能是以某种非标准方式创建的。感谢您在识别这一点并再次行动方面提供任何帮助。
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPageTree;
import org.apache.pdfbox.pdmodel.encryption.StandardDecryptionMaterial;
import org.apache.pdfbox.text.PDFTextStripperByArea;
import java.io.File;
import org.apache.pdfbox.pdmodel.PDPage;
import java.awt.Rectangle;
import java.util.List;
class Scratch {
private static float pwidth;
private static float pheight;
private static int widthByPercent(double percent) {
return (int)Math.round(percent * pwidth);
}
private static int heightByPercent(double percent) {
return (int)Math.round(percent * pheight);
}
public static void main(String[] args) {
try {
//Create objects
File inputStream = new File("ocr/TestDataFiles/i-9_08-07-09.pdf");
PDDocument document = PDDocument.load(inputStream);
// Try every decryption method I've found
if(document.isEncrypted()) {
// Method 1
document.decrypt("");
// Method 2
document.openProtection(new StandardDecryptionMaterial(""));
// Method 3
document.setAllSecurityToBeRemoved(true);
System.out.println("Removed encryption");
}
PDFTextStripperByArea stripper = new PDFTextStripperByArea();
//Get the page with data on it
PDPageTree allPages = document.getDocumentCatalog().getPages();
PDPage page = allPages.get(3);
pheight = page.getMediaBox().getHeight();
pwidth = page.getMediaBox().getWidth();
Rectangle LastName = new Rectangle(widthByPercent(0.02), heightByPercent(0.195), widthByPercent(0.27), heightByPercent(0.1));
stripper.addRegion("LastName", LastName);
stripper.setSortByPosition(true);
stripper.extractRegions(page);
List<String> regions = stripper.getRegions();
System.out.println(stripper.getTextForRegion("LastName"));
} catch (Exception e){
System.out.println(e.getMessage());
}
}
}
【问题讨论】:
-
为什么不使用 Acroform 字段呢?
doc.getDocumentCatalog().getAcroForm().getField("form1[0].#subform[3].address[0]").getValueAsString()。要获取所有字段的列表,请参阅源代码下载中的 PrintFields 示例。 -
可以使用两个密码加密 PDF:user 密码和 owner 密码。当 PDF 使用 user 密码加密时,如果不输入密码,您将无法在 PDF 查看器中打开文档。当 PDF 仅使用 owner 密码加密时,每个人都可以在没有该密码的情况下打开 PDF,但可能存在一些限制。您可以识别使用所有者密码加密的 PDF,因为它们在 Adobe Reader 中提及“安全”。您需要找到一种方法来忽略这种安全性,类似于在 iText 中使用“unethicalreading”标志。
-
@TilmanHausherr 是的!看来我的文档正在使用浮动注释,所以我的问题不在于解密,而是数据不在我认为的位置。我在一个信号很差的地区,所以 16MB 的信号源太多了,不过谢谢你,我什么时候回家看看!
标签: java encryption pdfbox