使用itextSharp5.5.10时RemoveField后userPassword无效

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

这是一个需要密码才能打开的PDF文件,我给它添加了电子签名。此后仍需要密码才能打开文件。但是我用AcroFields.RemoveField去掉电子签名后,打开文件就不需要密码了。这是正常的吗?如何在打开PDF文件时保留密码?

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

密码是 11111111

代码

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

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

根据负责保存加密信息的代码

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

(PdfStamperImp构造函数)

只有在追加模式下标记或设置了 unethicalreading 标志时才会发生这种情况。

在追加模式下测试您的代码时,发现该字段没有被删除。这是由于 AcroFields 字段删除代码未正确将 PDF 中的正确更新对象标记为 已使用。当你手动做标记时,它工作正常:

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, '[=11=]', 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));
    }
}

unethicalreading 标志设置为 true 的测试有效 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);
}