我不明白为什么PdfReader.ComputeUserPassword()返回null

时间:2019-07-15 09:54:36

标签: c# pdf itext

我正在尝试从PDF文件接收用户的密码。为了进行测试,我同时输入了主密码和用户密码。现在,我正在参数中传递主密码,并使用它来创建iTextSharp.text.pdf.PdfReader的新实例,该实例可以正常工作。然后,我输入一个if子句,该子句应返回是否以完全权限打开PDF。在此if子句中,我通过调用iTextSharp.text.pdf.PdfReader.ComputeUserPassword()并返回null来请求用户密码。


我的整个代码如下(GetByteAr(string s)返回转换为字节数组的密码):

public static bool IsPasswordProtectedOwner(string pdf, string ownerPw)
{

    try
    {
        var reader = new PdfReader(pdf, GetByteAr(ownerPw));
        if (reader.IsOpenedWithFullPermissions)
        {
            Console.WriteLine("opened with full permissions");
            string pw = String.Empty;
            var computedPassword = reader.ComputeUserPassword();
            foreach (byte b in computedPassword)
                pw += Char.ConvertFromUtf32(b);
        }
        else
        {
            Console.WriteLine("not opened with full permissions");
        }
    }
    catch (Exception e) when (e is NullReferenceException || e is BadPasswordException)
    {
        Console.WriteLine(e);
    }
    return true;
}

我的输出看起来像这样:

opened with full permissions
System.NullReferenceException: Object reference not set to an instance of an object.
   at PDFsV2.PDFInteractor.IsPasswordProtectedOwner(String pdf, String ownerPw) 
      in C:\Users\user\source\repos\PDFsV2\PDFsV2\PDFInteractor.cs:line 57

您能帮助我理解为什么computedPasswordnull吗?为什么ComputeUserPassword返回null

编辑,这就是它返回null的原因:

  

https://api.itextpdf.com/iText5/5.5.13/

     

公共字节[] computeUserPassword()

     

如果使用标准加密处理程序,则计算用户密码   Standard40,Standard128或AES128加密算法。

     

返回:       用户密码;如果未使用标准加密处理程序,则为null;如果将标准加密处理程序与AES256加密一起使用,则为   算法,或者如果未使用ownerPasswordUsed打开文档。

1 个答案:

答案 0 :(得分:1)

https://github.com/kusl/itextsharp/blob/master/tags/iTextSharp_5_4_5/src/core/iTextSharp/text/pdf/PdfReader.cs#L3849ComputeUserPassword的实现显示为:

public byte[] ComputeUserPassword() {
    if (!encrypted || !ownerPasswordUsed) return null;
    return decrypt.ComputeUserPassword(password);
}

根据该代码(第二行),ComputeUserPassword可能是null。因此,您需要在代码中满足要求(即在null之前检查它是否为foreach)。

在您的情况下,可能是因为:

ownerPasswordUsed = decrypt.ReadKey(enc, password);

返回false可能表明您输入的密码错误。

类似地,the docs状态:

  

用户密码,如果未使用标准加密处理程序,则为null   或未使用ownerPasswordUsed打开文档。