如何检查PDF文档是否有密码保护

13

我正在尝试使用iText的PdfReader来检查给定的PDF文件是否受到密码保护,但是却遇到了这个异常:

“Main Thread”线程中的异常java.lang.NoClassDefFoundError:org/bouncycastle/asn1/ASN1OctetString

但是当针对非密码保护文件测试相同的代码时,它可以正常运行。 这是完整的代码:

try {
    PdfReader pdf = new PdfReader("C:\\abc.pdf");
} catch (IOException e) {
    e.printStackTrace();
}

2
当你运行程序时,需要将BouncyCastle JAR文件包含在你的类路径中。 - Perception
8个回答

10

在旧版本的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 Box依赖项后,在运行应用程序时出现编译错误。 - andro-girl
这个可能性存在吗:它不会抛出 InvalidPasswordException,但仍然满足 encrypted = true 吗? - Bahadır Yağan
如果您尝试在未指定密码的情况下加载一个密码加密的PDF文件,它将抛出InvalidPasswordException异常,如文档所述。 - VHS

7
这里有一个不需要第三方库的解决方案,使用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

这是一个与Android平台相关的技术文档,介绍了如何使用PdfRenderer类来在应用程序中呈现PDF文档。

这里有一个解决方案,不需要第三方库。由于这个问题并不是特定于Android的(而路径“C:\abc.pdf”真正地暗示了另一个操作系统),Android图形PdfRenderer是第三方的... - mkl

6

使用Apache PDFBox - Java PDF库,从这里获取:
示例代码:

try
{
    document = PDDocument.load( "C:\\abc.pdf");

    if(document.isEncrypted())
    {
      //Then the pdf file is encrypeted.
    }
}

文档是一个类或接口的对象。 - tusharagrawa
@Tushar,上述代码片段中的“document”对象是类org.apache.pdfbox.pdmodel.PDDocument的一个对象。 - VHS
当我将这个库作为Gradle依赖项添加时,我遇到了编译问题。 - andro-girl
document.isEncrypted()验证是否已设置读取密码(正确回答该问题)。 请记住,可能无法执行加载(情况是:PDF已经加密)。 - sataniccrow

6

我的做法是尝试使用PdfReader读取PDF文件,当然不需要传递密码。如果文件受到密码保护,将会抛出BadPasswordException异常。这是使用iText库实现的。


我正在尝试相同的方法,但是异常无法被捕获。它仍然抛出上述异常。 - tusharagrawa
我相信你必须先解决ClassNotFound异常,然后它才能正常工作。 - Waleed Almadanat
尝试了很多次,但每当我使用PDFReader读取普通文件时,它都可以正常工作,但是当我尝试读取受密码保护的文件时,会出现Class Def not FoundException异常。 - tusharagrawa
1
这是因为处理受保护的文件需要使用BouncyCastle库。因此,如果你下载BouncyCastle并将其包含在项目的类路径中,你的代码就应该可以正常工作了。 - Waleed Almadanat

4
try {
    PdfReader pdfReader = new PdfReader(String.valueOf(file));
    pdfReader.isEncrypted();
} catch (IOException e) {
    e.printStackTrace();
}

使用iText PDF库,您可以检查PDF是否进入了异常处理程序(是否请求密码)。

1
请添加一个解释,说明为什么上述代码会起作用。 - Markoorn
@Markoorn - PdfReader允许您使用**isEncrypted()**检查文件是否受密码保护。如果PDF文件已加密(受密码保护),它将引发异常,在catch块中,您需要处理它或要求用户输入密码以打开文件。希望这可以帮助您。 - Shivam
1
即使对于未使用密码保护的文件,它仍然返回true。 - andro-girl
1
@andro-girl 你在使用哪个库?确保使用的是iText(implementation 'com.itextpdf:itextg:5.5.10')。这个对我来说是有效的。 - Shivam

2
尝试这段代码:

尝试这段代码:

    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。请注意,某些文档受密码保护,但用户密码为空。 - Tilman Hausherr

1
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);

0

我不想使用任何第三方库,所以我使用了这个 -

            try {
                new PdfRenderer(ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY));
            } catch (Exception e) {
                e.printStackTrace();
                // file is password protected
            }

如果文件有密码保护,我就不会使用它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接