drekx
drekx

Reputation: 13

Itextsharp cannot open files with password if 128 bit rc4

I have password protected pdf files that I'm trying to open to disable the password protection. I have been able to do it with samples that are 128 bit aes but most of the files I will be dealing with in production are 128 bit rc4. Whenever I try the following code on 128 bit rc4 it failes and gives me the error: Bad User Password.

try
{
    PdfReader reader = new PdfReader(InputFile, new System.Text.ASCIIEncoding().GetBytes(password));
    using (MemoryStream memoryStream = new MemoryStream())
    {
         PdfStamper stamper = new PdfStamper(reader, memoryStream);
         stamper.Close();
         reader.Close();
         File.WriteAllBytes(OutputFile, memoryStream.ToArray());
    }
}
catch (Exception ex)
{
    Console.WriteLine(InputFile + " ::::: " + password + " ---> " + ex.Message);
}

For sample pdf: https://drive.google.com/file/d/0BxDisLjTqrx8QnFQQ013SFhmdGM/edit?usp=sharing pass on file is: 123456 obvious this is just for testing purposes ;)

Upvotes: 1

Views: 917

Answers (1)

Chris Haas
Chris Haas

Reputation: 55427

(comments to answer)

This appears to be a problem with the mPDF library that produced the pdf in question. Per the spec, section 3.5.2:

PDF integer objects are represented internally in signed twos-complement form. Since all the reserved high-order flag bits in the encryption dictionary's P value are required to be 1, the value must be specified as a negative number.

The PDF in question has a /P value of 4294967292 which according to the spec is incorrect. If my math is correct it should actually be -4. Changing the iTextSharp manually to use this -4 permission for SetupByUserPassword in PdfEncrption.cs allows decryption to succeed.

iTextSharp uses an Int32 to hold the permissions which maxes out at 2,147,483,647. When .Net converts from your string of 4294967292 it starts as a Float and then .Net tries to cast it to Int32 but per the C# spec it fails and returns an "unspecified value of the destination type".

When you convert from a double or float value to an integral type, the value is truncated. If the resulting integral value is outside the range of the destination value, the result depends on the overflow checking context. In a checked context, an OverflowException is thrown, while in an unchecked context, the result is an unspecified value of the destination type.

Adobe and other libraries might be using a wider type like a 64-bit integer which is why they are able to open the PDF.

The solution for the OP was to change parts of iTextSharp's source from Int32 to Int64. This OK for their very specific situation but I wouldn't recommend it for most people unless they have a good grasp of the crypto algorithms used. Ideally this should be fixed with mPDF and possibly iText could add support to handle this invalid value.

Upvotes: 1

Related Questions