Vibhu Dadhichi
Vibhu Dadhichi

Reputation: 1129

BadPasswordException: Bad user password

I am creating an encrypted PDF using this code:

Document document = new Document(
    new Rectangle(PageSize.A4.getWidth(), PageSize.A4.getHeight()));
PdfWriter writer = PdfWriter.getInstance(document,
    new FileOutputStream(RESULT1));
writer.setBoxSize("art", new Rectangle(36, 54, 555, 791));
writer.setEncryption("Vibhu".getBytes(), "Vibhu@123456789".getBytes(),
    PdfWriter.ALLOW_PRINTING, PdfWriter.ENCRYPTION_AES_128);
document.open();
// Creating Tables and Cells
document.close();

I omitted to code that creates cells and tables and the code that creates a form in which values such as firstname, lastname can be entered.

Then I manipulate the form like this.

private void manipulatePdf(String src, String dest, EclaimsVO eclaimsVO,
    String language) throws IOException, DocumentException {
    File file = new File(src);
    if (isObjectPresent(file)) {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper;
        stamper = new PdfStamper(reader, new FileOutputStream(dest),
                '\0', false);
        form = stamper.getAcroFields();
        addToForm("field_2", eclaimsVO.getName());
        addToForm("field_3", eclaimsVO.getSurName());
        stamper.close();
    }
}

I have been trying to add a password to a PDF file by setEncryption() when I create the file, but it throws this exception when I read the file:

com.itextpdf.text.exceptions.BadPasswordException: Bad user password
at com.itextpdf.text.pdf.PdfReader.readPdf(PdfReader.java:681)
at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:181)
at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:219)
at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:207)
at com.itextpdf.text.pdf.PdfReader.<init>(PdfReader.java:197)

But, if I change the unethicalreading to true and set the OWNER-PASSWORD as an empty string the exception doesn't come up.

writer.setEncryption("".getBytes(), "Vibhu@123456789".getBytes(),
            PdfWriter.ALLOW_PRINTING, PdfWriter.ENCRYPTION_AES_128);
PdfReader.unethicalreading = true;

And now when I try opening the PDF it gets opened without a password prompt. But the document has a "Sample.pdf(SECURED)" title when I open the PDF.

Upvotes: 1

Views: 7889

Answers (1)

Bruno Lowagie
Bruno Lowagie

Reputation: 77528

First allow me to focus on some details:

Document document = new Document(
    new Rectangle(PageSize.A4.getWidth(), PageSize.A4.getHeight()));

The constance A4 is a Rectangle object with a specific width and height. You can use it like this:

Document document = new Document(PageSize.A4);

Why are you creating yet another rectangle? new Rectangle(PageSize.A4.getWidth(), PageSize.A4.getHeight()) is the equivalent of PageSize.A4, so why aren't you just using PageSize.A4?

Why are you defining an art box?

writer.setBoxSize("art", new Rectangle(36, 54, 555, 791));

There is usually very little reason to create an Art box. Why not remove this line?

Now for the essence of your question:

First counter-question:

It seems that you are creating a form that you later want to fill out. If this form is meant for private use, why are you encrypting the form? Why not encrypt it during the process of filling it out? Wouldn't that simplify things?

Short description of what you're doing:

Suppose that you really want to encrypt the template. In that case, you know the owner password:

writer.setEncryption("Vibhu".getBytes(), "Vibhu@123456789".getBytes(),
    PdfWriter.ALLOW_PRINTING, PdfWriter.ENCRYPTION_AES_128);

You also tried:

writer.setEncryption("".getBytes(), "Vibhu@123456789".getBytes(),
    PdfWriter.ALLOW_PRINTING, PdfWriter.ENCRYPTION_AES_128);

You claim that you set the OWNER-PASSWORD as an empty string. That is not true! You are using an empty String for the user password. The user password is the password that an end user (a human being who want to read the document) needs to enter when he wants to open the document. The owner password is the password unknown to the user that is introduced by the person creating the document. This person will use that password when he wants to change something in the document, for instance: when he wants to fill out a form.

Second counter-question:

Why are you using this line:

PdfReader.unethicalreading = true;

This line is what people use when they don't know the owner password. However, you do know the owner password: it's "Vibhu@123456789".

The simple solution to avoid a BadPasswordException:

Since you know the owner password, you should use it when reading the document. This is explained in my answer to the question How can I decrypt a PDF document with the owner password?

You should update the line where you create the reader object like this:

PdfReader reader = new PdfReader(src, "Vibhu@123456789".getBytes());

Now you will no longer get a BadPasswordException and you can safely fill out your form.

Upvotes: 8

Related Questions