【问题标题】: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。

标签: java passwords itext file-permissions pdf-reader


【解决方案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
                }
    

    如果文件受密码保护,我没有使用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-19
      • 2023-03-26
      • 1970-01-01
      • 2019-07-01
      • 2023-03-03
      • 1970-01-01
      • 2015-08-24
      • 2013-02-05
      相关资源
      最近更新 更多