Yinxf
Yinxf

Reputation: 57

The userPassword is invalid after RemoveField when itextSharp5.5.10 is used

Here is a PDF file that requires a password to open, and I added an electronic signature to it. A password is still required to open the file after this. But after I use AcroFields.RemoveField to remove the electronic signature, a password is no longer required to open the file. Is this normal? How can I keep the password when opening the PDF file?

test pdf https://github.com/IYinxf/PDFs/blob/master/Encrypted.pdf

password is 11111111

code

pdfReader = new PdfReader(strTempPath, Encoding.ASCII.GetBytes(strPassword));
if (!pdfReader.IsOpenedWithFullPermissions)
{
    return ERR_PERMISSION_DENIED;
}

AcroFields af = pdfReader.AcroFields;
bool rv = af.RemoveField(fieldName);

Upvotes: 1

Views: 63

Answers (1)

mkl
mkl

Reputation: 95918

According to the code responsible for keeping encryption information

if (reader.IsEncrypted() && (append || PdfReader.unethicalreading)) {
    crypto = new PdfEncryption(reader.Decrypt);
}

(PdfStamperImp constructor)

this only happens if you are stamping in append mode or if the unethicalreading flag is set.

When testing your code in append mode, it turns out that the field is not removed. This is caused by the AcroFields field removal code not properly marking the correct updated objects in your PDF as used. When you do the marking manually, it works fine:

using (var pdfReader = new PdfReader(file, Encoding.ASCII.GetBytes(strPassword)))
using (FileStream output = new FileStream(outputFilePath, FileMode.Create, FileAccess.Write))
using (PdfStamper pdfStamper = new PdfStamper(pdfReader, output, '\0', true))
{
    AcroFields af = pdfReader.AcroFields;
    bool rv = af.RemoveField(fieldName);
    pdfStamper.MarkUsed(pdfReader.Catalog);
    for (int pageNo = 1; pageNo <= pdfReader.NumberOfPages; pageNo++)
    {
        pdfStamper.MarkUsed(pdfReader.GetPageN(pageNo));
    }
}

Testing with the unethicalreading flag set to true works out-of-the-box:

PdfReader.unethicalreading = true;
using (var pdfReader = new PdfReader(file, Encoding.ASCII.GetBytes(strPassword)))
using (FileStream output = new FileStream(outputFilePath, FileMode.Create, FileAccess.Write))
using (PdfStamper pdfStamper = new PdfStamper(pdfReader, output))
{
    AcroFields af = pdfReader.AcroFields;
    bool rv = af.RemoveField(fieldName);
}

Upvotes: 1

Related Questions