4

如何在java中检查pdf文件是否受密码保护?我知道有几个工具/库可以做到这一点,但我想知道这是否可以用 java 中的程序来实现。

4

5 回答 5

3

您可以使用 PDFBox:

http://pdfbox.apache.org/

代码示例:

try
{
    document = PDDocument.load( yourPDFfile );

    if( document.isEncrypted() )
    {
      //ITS ENCRYPTED!
    }
}

使用行家?

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0</version>
</dependency>
于 2013-02-11T06:26:01.877 回答
3

更新

根据 mkl 在此答案下方的评论,规范似乎允许使用两种类型的 PDF 结构:(1)交叉引用表(2)交叉引用流。以下解决方案仅针对第一种类型的结构。需要更新此答案以解决第二种类型。

====

上面提供的所有答案都引用了一些第三方库,这是 OP 已经知道的。OP 要求使用本机 Java 方法。我的回答是肯定的,你可以做到,但这需要大量的工作。

这将需要一个两步过程:

第 1 步确定 PDF 是否已加密

根据 Adob​​e 的 PDF 1.7规范(第 97 和 115 页),如果预告片记录包含密钥“\Encrypted”,则 pdf 被加密(加密可以是简单的密码保护或 RC4 或 AES 或一些自定义加密)。这是一个示例代码:

    Boolean isEncrypted = Boolean.FALSE;
    try {
        byte[] byteArray = Files.readAllBytes(Paths.get("Resources/1.pdf"));
        //Convert the binary bytes to String. Caution, it can result in loss of data. But for our purposes, we are simply interested in the String portion of the binary pdf data. So we should be fine.
        String pdfContent = new String(byteArray);
        int lastTrailerIndex = pdfContent.lastIndexOf("trailer");
        if(lastTrailerIndex >= 0 && lastTrailerIndex < pdfContent.length()) {
            String newString =  pdfContent.substring(lastTrailerIndex, pdfContent.length());
            int firstEOFIndex = newString.indexOf("%%EOF");
            String trailer = newString.substring(0, firstEOFIndex);
            if(trailer.contains("/Encrypt"))
                isEncrypted = Boolean.TRUE;
        }
    }
    catch(Exception e) {
        System.out.println(e);
        //Do nothing
    }

第 2 步找出加密类型

这一步比较复杂。我还没有代码示例。但这里是算法:

  1. 从上面的步骤 1 中读取的预告片中读取密钥“/Encrypt”的值。例如,该值为 288 0 R。
  2. 查找字节“288 0 obj”。这是文档中“加密字典”对象的位置。该对象边界以字符串“endobj”结束。
  3. 在此对象中查找键“/Filter”。“过滤器”是识别文档安全处理程序的过滤器。如果“/Filter”的值为“/Standard”,则文档使用内置的基于密码的安全处理程序。

如果您只想知道 PDF 是否被加密,而不用担心加密是所有者/用户密码或某些高级算法的形式,则不需要上面的第 2 步。

希望这可以帮助。

于 2016-12-27T22:43:44.553 回答
1

使用iText pdf API,我们可以识别受密码保护的 PDF。

例子 :

    try {
            new PdfReader("C:\\Password_protected.pdf");            
        } catch (BadPasswordException e) {
            System.out.println("PDF is password protected..");
        } catch (Exception e) {
            e.printStackTrace();
        }
于 2013-02-11T06:59:36.283 回答
0

您可以使用 Itext 验证 pdf,即它是否可读、可写。

以下是代码片段,

boolean isValidPdf = false;
try {
    InputStream tempStream = new FileInputStream(new File("path/to/pdffile.pdf"));
    PdfReader reader = new PdfReader(tempStream);
    isValidPdf = reader.isOpenedWithFullPermissions();
    } catch (Exception e) {
        isValidPdf = false;
    }
于 2016-05-20T15:41:04.457 回答
-1

解决方案:

1) 安装 PDF Parser http://www.pdfparser.org/

2) 在本节编辑 Parser.php:

if (isset($xref['trailer']['encrypt'])) {
echo('Your Allert message');
exit();}

3)在您的 .php 表单帖子(例如 upload.php)中插入:

for the first require  '...yourdir.../vendor/autoload.php';

然后写这个函数:

function pdftest_is_encrypted($form) {
$parser = new \Smalot\PdfParser\Parser();
$pdf    = $parser->parseFile($form);
}

然后调用函数

pdftest_is_encrypted($_FILES["upfile"]["tmp_name"]);

这就是全部,如果您尝试使用密码加载 PDF,系统会返回错误“您的警报消息”

于 2015-05-31T20:20:38.847 回答