Disallow editing but allow page extraction in Java

2019-04-07 14:21发布

问题:

I'm using iText to generate PDF files. I want to disallow editing of the PDF, but allow the reader to extract pages. Here's my code to set encryption:

writer.setEncryption(null, null, 0xffffffff, PdfWriter.STANDARD_ENCRYPTION_128);

The third parameter specifies permissions. I'm using 0xffffffff instead of the individual iText flags ALLOW_PRINTING etc. This will ask iText to enable everything. But this is what I get in the PDF file:

I should think I should be allowed to enable extraction but disable editing, but am not certain. Here are the permissions bits per Adobe:

(From here, but be warned it's 30 meg)

So turn off bits 6 and 11 but leave on the others (especially bits 5 and 10), and that would turn off editing but allow extraction. In any case, by specifying 0xffffffff I would think that everything would be allowed; but instead everything except extraction is allowed.

I've skimmed the iText source code for setting permissions and don't see anything that would cause this. Here is the relevant code from PdfEncryption.setupAllKeys:

permissions |= (revision == STANDARD_ENCRYPTION_128 || revision == AES_128 || revision == AES_256) ? 0xfffff0c0
        : 0xffffffc0;
permissions &= 0xfffffffc;

The first line is doing an OR and so wouldn't remove any permissions; the second line is setting the two right-most bites to 0, per the PDF specification.

I'm wondering if it's an iText thing, a PDF thing or if I'm doing something else wrong.

Thanks

回答1:

A similar issue already has been raised here.

Using encryption actually is counter-productive as it can only be used to remove permissions, not to add them.

According to this, it might be helpful to completely unlock the PDF first:

PdfReader reader = new PdfReader(file.toURI().toURL());
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(
    file.getAbsolutePath().replace(".pdf", "_UNLOCKED.pdf")));
stamper.close();
reader.close();

Afterwards you can grab the output and start from scratch (mess around with the permission bits). Hope this helps.

EDIT: If you don't have access to the password, the iText sources can be modified. Simply comment out if (!reader.isOpenedWithFullPermissions()) throw ... (line 121 and 122 in version 5.5.0) in com.itextpdf.text.pdf.PdfStamperImp.