如何检查pdf文件是否受密码保护i

时间:2013-02-11 06:17:24

标签: java pdf

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

5 个答案:

答案 0 :(得分:3)

你可以使用PDFBox:

http://pdfbox.apache.org/

代码示例:

try
{
    document = PDDocument.load( yourPDFfile );

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

使用maven?

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0</version>
</dependency>

答案 1 :(得分:2)

更新

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

====

上面提供的所有答案都指的是OP已经知道的一些第三方库。 OP正在寻求原生Java方法。我的回答是肯定的,你可以做到,但这需要很多工作。

这需要两个步骤:

第1步确定PDF是否已加密

根据Adobe的PDF 1.7 specs(第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”,则文档使用内置的基于密码的安全性处理程序。
  4. 如果您只是想知道PDF是否加密而不必担心加密是否采用所有者/用户密码或某些高级算法,则您不需要上面的步骤2.

    希望这有帮助。

答案 2 :(得分: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();
        }

答案 3 :(得分:1)

您可以使用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;
    }

答案 4 :(得分:-1)

解决方案:

1)安装PDF解析器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,系统会返回错误&#34;您的Allert消息&#34;