如何检查 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 是不是受密码保护的主要内容,如果未能解决你的问题,请参考以下文章

如何检查文件是不是通过 7zip 受密码保护?

如何检查 InputStream 7Z 存档文件是不是受密码保护?

iTextsharp PDF 文档属性

如何创建受密码保护的 pdf 文件

如何使用 iText 7 删除受密码保护的 pdf 中的密码

检查是不是为当前受版权保护的程序集制作了许可文件