如何检查 PDF 是不是受密码保护
Posted
技术标签:
【中文标题】如何检查 PDF 是不是受密码保护【英文标题】:How to check if a PDF is Password Protected or not如何检查 PDF 是否受密码保护 【发布时间】:2013-03-31 13:45:32 【问题描述】:我正在尝试使用 iText 的 PdfReader 来检查给定的 PDF 文件是否受密码保护,但出现此异常:
线程“主线程”中的异常 java.lang.NoClassDefFoundError:org/bouncycastle/asn1/ASN1OctetString
但是当针对非密码保护的文件测试相同的代码时,它运行良好。完整代码如下:
try
PdfReader pdf = new PdfReader("C:\\abc.pdf");
catch (IOException e)
e.printStackTrace();
【问题讨论】:
运行程序时,您需要在类路径中包含 BouncyCastle JAR。 【参考方案1】:在旧版 PDFBox 中
try
InputStream fis = new ByteArrayInputStream(pdfBytes);
PDDocument doc = PDDocument.load(fis);
if(doc.isEncrypted())
//Then the pdf file is encrypeted.
在较新版本的 PDFBox(例如 2.0.4)中
InputStream fis = new ByteArrayInputStream(pdfBytes);
boolean encrypted = false;
try
PDDocument doc = PDDocument.load(fis);
if(doc.isEncrypted())
encrypted=true;
doc.close();
catch(InvalidPasswordException e)
encrypted = true;
return encrypted;
【讨论】:
添加 pdf 框依赖后,在运行应用程序时出现编译错误。【参考方案2】:使用 Apache PDFBox - 来自here 的 Java PDF 库:示例代码:
try
document = PDDocument.load( "C:\\abc.pdf");
if(document.isEncrypted())
//Then the pdf file is encrypeted.
【讨论】:
文档是哪个类或接口的对象 @Tushar,上面代码sn-p中的“document”对象是org.apache.pdfbox.pdmodel.PDDocument类的对象。 当我将此库添加为 gradle 依赖项时,我正在编译 document.isEncrypted() 验证是否已设置读取密码(正确回答问题)。无论如何请记住,可能无法执行加载(案例是:pdf已被真实加密)【参考方案3】:我这样做的方法是尝试使用 PdfReader
读取 PDF 文件,当然不传递密码。如果文件受密码保护,则会抛出BadPasswordException
。这是使用 iText 库。
【讨论】:
我正在尝试相同的方法,但无法捕获异常。它仍然在抛出上述异常, 我相信你必须先解决 ClassNotFound 异常,然后它才会起作用。 已经尝试了很多次,但是每当我使用 PDFReader 读取普通文件时,它都可以正常工作,但是当我尝试读取受密码保护的文件时,会发生 Class Def not FoundException 这是因为处理受保护的文件需要 BouncyCastle 库。因此,如果您 download BouncyCastle 并将其包含在项目的类路径中,您的代码应该可以正常工作。【参考方案4】:这是一个不需要 3rd 方库的解决方案,使用 PdfRenderer API。
fun checkIfPdfIsPasswordProtected(uri: Uri, contentResolver: ContentResolver): Boolean
val parcelFileDescriptor = contentResolver.openFileDescriptor(uri, "r")
?: return false
return try
PdfRenderer(parcelFileDescriptor)
false
catch (securityException: SecurityException)
true
参考:https://developer.android.com/reference/android/graphics/pdf/PdfRenderer
【讨论】:
“这是一个不需要 3rd 方库的解决方案” - 因为问题不是特定于 Android 的(并且路径"C:\\abc.pdf"
确实暗示了另一个操作系统) ,Android 图形 PdfRenderer 是第 3 方...【参考方案5】:
try
PdfReader pdfReader = new PdfReader(String.valueOf(file));
pdfReader.isEncrypted();
catch (IOException e)
e.printStackTrace();
使用 iText PDF 库您可以检查。如果它发生异常处理它(要求输入密码)
【讨论】:
请解释为什么上述方法会起作用。 @Markoorn - PdfReader 允许您使用 **isEncrypted() ** 检查文件是否受密码保护。如果 pdf 文件被加密(密码保护)它会给你一个例外,在 catch 块你需要处理它或要求用户输入密码来打开文件。希望对你有帮助。 即使对于非密码保护的文件,它也会返回 true。 @andro-girl 您使用的是哪个库?确保 iText(实现 'com.itextpdf:itextg:5.5.10')。它对我有用。【参考方案6】:试试这个代码:
boolean isProtected = true;
PDDocument pdfDocument = null;
try
pdfDocument = PDDocument.load(new File("your file path"));
isProtected = false;
catch(Exception e)
LOG.error("Error while loading file : ",e);
Syste.out.println(isProtected);
如果您的文档受密码保护,则它无法加载文档并抛出 IOException。
使用pdfbox-2.0.4.jar
验证上述代码
【讨论】:
更准确地说:它会抛出 InvalidPasswordException,这是一个 IOException。请注意,有些文档受密码保护,但用户密码为空。【参考方案7】:public boolean checkPdfEncrypted(InputStream fis) throws IOException
boolean encrypted = false;
try
PDDocument doc = PDDocument.load(fis);
if (doc.isEncrypted())
encrypted = true;
doc.close();
catch (
IOException e)
encrypted = true;
return encrypted;
注意:在 iText 中有一个极端情况,一些文件被加密保护但没有密码打开,读取这些文件并像这样添加水印
PdfReader reader = new PdfReader(src);
reader.setUnethicalReading(true);
【讨论】:
【参考方案8】:我不想使用任何第三方库,所以我使用了这个 -
try
new PdfRenderer(ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY));
catch (Exception e)
e.printStackTrace();
// file is password protected
如果文件受密码保护,我没有使用它。
【讨论】:
以上是关于如何检查 PDF 是不是受密码保护的主要内容,如果未能解决你的问题,请参考以下文章
如何检查 InputStream 7Z 存档文件是不是受密码保护?