2

I have a PDF file locked with owner and user password. I don't have the owner password but I have the user password.

I am using iText to decrypt the file

So how should I decrypt the PDF file.

public class Decrypt {

  public static final String SRC = "D:\\GitCodeBase(Master)\\pdf\\src\\main\\resources\\encrypt\\abc.pdf";
  public static final String DEST = "D:\\GitCodeBase(Master)\\pdf\\src\\main\\resources\\decrypt\\def.pdf";

  public static void main(String[] args) throws Exception {
      PdfReader.unethicalreading = true;
      PdfReader reader = new PdfReader(SRC,"abc123".getBytes());
      PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(DEST));
      stamper.close();
      reader.close();
  }
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
neo
  • 47
  • 1
  • 7
  • The question this question is marked a duplicate of was about iTextSharp but the solution also applies to iText. And only having the user password implies not having the owner password and, therefore, is the same situation as far as operations requiring the owner password are concerned. – mkl Jul 27 '17 at 13:27
  • @mkl this is not duplicate, I dnt find any solution there – neo Jul 27 '17 at 16:15
  • Have you tried `PdfReader.unethicalreading = true` in combination with your user password? If that doesn't work, this may not be a duplicate. But in that case there is something special about your PDF, so we'd need it to help. – mkl Jul 27 '17 at 18:26
  • @mkl Yes as u see I tried PdfReader.unethicalreading = true with my user password but still it is not decrypted,while opening i still need password to open. – neo Jul 28 '17 at 02:55
  • Then please share the PDF in question for analysis. – mkl Jul 28 '17 at 05:04
  • @mkl Here is the link for pdf [link](https://www.dropbox.com/s/pc74oox4y19awin/abc.pdf?dl=0) – neo Jul 28 '17 at 07:13
  • I'm afraid I do not get that exception. (The result is not decrypted either, but that is a different matter.) Thus, please check whether `D:\GitCodeBase(Master)\pdf\src\main\resources\encrypt\abc.pdf` is still in the state you expect it to be. – mkl Jul 28 '17 at 13:28
  • @mkl i am also not getting exception when i use unethicalreading = true,but this dont solve my problem.code executed w/o any error but the end result which i want is not fulfil – neo Jul 29 '17 at 06:25
  • *i am also not getting exception when i use unethicalreading = true* - your question currently claims you do get it... ;) – mkl Jul 29 '17 at 09:37

1 Answers1

3

Using your code and your example file, I unfortunately cannot reproduce the issue: The code executes without throwing an exception.

But it does not yet do what you want either: The result file still is encrypted. Thus, here some information on that.


If you read Bruno's answer here up to its end, you'll see that your code used to decrypt PDF files before iText 5.3.5. Meanwhile, though, the encryption is kept. Strictly speaking that indeed is more correct, after all the code nowhere asks iText to drop the encryption.

Thus, in current iText 5 versions (I'm using the current 5.5.12-SNAPSHOT maintenance version), you have to do a bit more, you have to fool iText into thinking that the PDF wasn't encrypted as Bruno put it in his answer.

Unfortunately the member variable of PdfReader you have to change to do that is not public. Thus, you cannot simply set it.

The member in question is protected. Thus, you can change it by deriving your own PdfReader subclass and use a method in it to do the change. This has been demonstrated in Bruno's answer, here a variation for non-empty user passwords:

class MyReader extends PdfReader {
    public MyReader(final String filename, final byte password[]) throws IOException {
        super(filename, password);
    }
    public void decryptOnPurpose() {
        encrypted = false;
    }
}

public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
    MyReader.unethicalreading = true;
    MyReader reader = new MyReader(src, "abc123".getBytes());
    reader.decryptOnPurpose();
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
    stamper.close();
    reader.close();
}

Alternatively you can also use reflection:

PdfReader.unethicalreading = true;
PdfReader reader = new PdfReader(inputStream, "abc123".getBytes());

Field encryptedField = PdfReader.class.getDeclaredField("encrypted");
encryptedField.setAccessible(true);
encryptedField.set(reader, false);

PdfStamper stamper = new PdfStamper(reader, outputStream);
stamper.close();
reader.close();

(DecryptUserOnly.java test method testDecryptAbc)


PS: I am aware that this answer hardly adds anything to Bruno's original answer. I did not try to mark this question a duplicate of the question of that answer only because it has been "closed as off-topic" and because numerous links in that answer meanwhile have become stale.

mkl
  • 90,588
  • 15
  • 125
  • 265