简体   繁体   English

如何查看pdf文件是否有密码保护?

[英]How to check pdf file is password protected?

How to check pdf file is password protected or not in java?如何在java中查看pdf文件是否有密码保护? I know of several tools/libraries that can do this but I want to know if this is possible with just program in java.我知道有几个工具/库可以做到这一点,但我想知道仅使用 java 中的程序是否可行。

you can use PDFBox:您可以使用 PDFBox:

http://pdfbox.apache.org/ http://pdfbox.apache.org/

code example :代码示例:

try
{
    document = PDDocument.load( yourPDFfile );

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

using maven?使用Maven?

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

Update更新

As per mkl's comment below this answer, it seems that there are two types of PDF structures permitted by the specs: (1) Cross-referenced tables (2) Cross-referenced Streams.根据 mkl 在此答案下方的评论,似乎规范允许两种类型的 PDF 结构:(1) 交叉引用表 (2) 交叉引用流。 The following solution only addresses the first type of structure.以下解决方案仅针对第一种类型的结构。 This answer needs to be updated to address the second type.需要更新此答案以解决第二种类型。

==== ====

All of the answers provided above refer to some third party libraries which is what the OP is already aware of.上面提供的所有答案都参考了一些第三方库,这是 OP 已经知道的。 The OP is asking for native Java approach. OP 要求使用本机 Java 方法。 My answer is yes, you can do it but it will require a lot of work.我的回答是肯定的,你可以做到,但需要做很多工作。

It will require a two step process:这将需要一个两步过程:

Step 1 : Figure out if the PDF is encrypted第 1 步确定 PDF 是否已加密

As per Adobe's PDF 1.7 specs (page number 97 and 115), if the trailer record contains the key "\\Encrypted", the pdf is encrypted (the encryption could be simple password protection or RC4 or AES or some custom encryption).根据 Adob​​e 的 PDF 1.7 规范(第 97 和 115 页),如果预告片记录包含密钥“\\Encrypted”,则 pdf 将被加密(加密可以是简单的密码保护或 RC4 或 AES 或某些自定义加密)。 Here's a sample code:这是一个示例代码:

    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
    }

Step 2 : Figure out the encryption type第 2 步找出加密类型

This step is more complex.这一步比较复杂。 I don't have a code sample yet.我还没有代码示例。 But here is the algorithm:但这是算法:

  1. Read the value of the key "/Encrypt" from the trailer as read in the step 1 above.从上面的步骤 1 中读取的预告片中读取密钥“/Encrypt”的值。 Eg the value is 288 0 R.例如,值为 288 0 R。
  2. Look for the bytes "288 0 obj".查找字节“288 0 obj”。 This is the location of the "encryption dictionary" object in the document.这是文档中“加密字典”对象的位置。 This object boundary ends at the string "endobj".该对象边界以字符串“endobj”结束。
  3. Look for the key "/Filter" in this object.在此对象中查找键“/Filter”。 The "Filter" is the one that identifies the document's security handler. “过滤器”是标识文档安全处理程序的过滤器。 If the value of the "/Filter" is "/Standard", the document uses the built-in password-based security handler.如果“/Filter”的值为“/Standard”,则文档使用内置的基于密码的安全处理程序。

If you just want to know whether the PDF is encrypted without worrying about whether the encryption is in form of owner / user password or some advance algorithms, you don't need the step 2 above.如果您只想知道 PDF 是否已加密,而不必担心加密是采用所有者/用户密码形式还是某些高级算法,则不需要上述步骤 2。

Hope this helps.希望这可以帮助。

Using iText pdf API we can identify the password protected PDF.使用iText pdf API,我们可以识别受密码保护的 PDF。

Example :例子 :

    try {
            new PdfReader("C:\\Password_protected.pdf");            
        } catch (BadPasswordException e) {
            System.out.println("PDF is password protected..");
        } catch (Exception e) {
            e.printStackTrace();
        }

You can validate pdf, ie it can be readable, writable by using Itext.您可以验证pdf,即它可以通过使用Itext 可读可写。

Following is the code snippet,以下是代码片段,

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;
    }

The correct how to do it in java answer is per @vhs. java 答案中的正确操作方法是每个@vhs。

However in any application by far the simplest is to use very lightweight pdfinfo tool to filter the encryption status and here using windows cmd I can instantly get a report that two different copies of the same file are encrypted然而,在任何应用程序中,最简单的是使用非常轻量级的 pdfinfo 工具来过滤加密状态,在这里使用 windows cmd 我可以立即得到一份报告,同一文件的两个不同副本被加密

>forfiles /m *.pdf /C "cmd /c echo @file &pdfinfo @file|find /i \"Encrypted\""

"Certificate (9).pdf"
Encrypted:      no

"ds872 source form.pdf"
Encrypted:      AES 128-bit

"ds872 filled form.pdf"
Encrypted:      AES 128-bit

"How to extract data from a particular area in a PDF file - Stack Overflow.pdf"
Encrypted:      no

"Test.pdf"
Encrypted:      no

>

The solution:解决方案:

1) Install PDF Parser http://www.pdfparser.org/ 1) 安装 PDF 解析器http://www.pdfparser.org/

2) Edit Parser.php in this section: 2) 在此部分编辑 Parser.php:

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

3)In your .php form post ( ex. upload.php) insert this: 3)在你的 .php 表单帖子(例如upload.php)中插入:

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

then write this function:然后写这个函数:

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

and then call the function然后调用函数

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

This is all, if you'll try to load a PDF with password the system return an error "Your Allert message"这就是全部,如果您尝试使用密码加载 PDF,系统将返回错误“您的警报消息”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM