使用iTextSharp打开受密码保护的pdf文件

我正在制作一个应该显示带密码的PDF的应用程序。 这是我的代码:

protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { try { string filePath = Request.QueryString["filePath"]; if (filePath.ToUpper().EndsWith("PDF")) { copyPDF(filePath); } } catch { string message = "alert('File Not Found! Call Records Department for verification. ')"; ScriptManager.RegisterStartupScript(Page, this.GetType(), message, message, false); } } } public void copyPDF(string filePath) { iTextSharp.text.pdf.RandomAccessFileOrArray ra = new iTextSharp.text.pdf.RandomAccessFileOrArray(Server.MapPath(ResolveUrl(filePath))); if (ra != null) { System.IO.MemoryStream ms = new System.IO.MemoryStream(); byte[] password = System.Text.ASCIIEncoding.ASCII.GetBytes("Secretinfo"); iTextSharp.text.pdf.PdfReader thepdfReader = new iTextSharp.text.pdf.PdfReader(ra, password); int pages = thepdfReader.NumberOfPages; iTextSharp.text.Document pdfDoc = new iTextSharp.text.Document(); iTextSharp.text.pdf.PdfCopy pdfCopy = new iTextSharp.text.pdf.PdfCopy(pdfDoc, ms); pdfDoc.Open(); int i = 0; while (i < pages) { pdfCopy.AddPage(pdfCopy.GetImportedPage(thepdfReader, i + 1)); i += 1; } pdfDoc.Close(); Byte[] byteInfo = ms.ToArray(); Response.Clear(); Response.ContentType = "application/pdf"; Response.AddHeader("content-length", byteInfo.Length.ToString()); Response.BinaryWrite(byteInfo); Response.Flush(); Response.End(); } } 

我的代码在没有密码的情况下打开pdf文件没有问题,但即使提供了密码也无法用密码打开pdf。 应用程序执行catch。 我的代码似乎有什么问题?

编辑 :我删除了Catch以查看抛出的exception。

exception详细信息 :System.ArgumentException:PdfReader未使用所有者密码打开

它说错误的来源是第51行。

 Line 49: while (i < pages) Line 50: { Line 51: pdfCopy.AddPage(pdfCopy.GetImportedPage(thepdfReader, i + 1)); Line 52: i += 1; Line 53: } 

对于加密文档的某些操作,iText(夏普)要求不仅使用用户密码打开文档,而且使用所有者密码打开文档。 这对应于PDF规范中这些密码的定义:

是否允许对解密文档执行其他操作取决于打开文档时提供的密码(如果有)以及创建文档时指定的任何访问限制:

  • 使用正确的所有者密码打开文档应该允许完全(所有者)访问文档。 这种无限制访问包括更改文档密码和访问权限的function。
  • 使用正确的用户密码打开文档(或使用默认密码打开文档)应允许根据文档加密字典中指定的用户访问权限执行其他操作。

( ISO 32000-1中的第7.6.3.1节)

iText(夏普)目前没有详细检查文档加密字典中指定的用户访问权限,而是始终要求所有者密码用于需要特定权限的操作,并且最终从文档复制整个页面就是其中之一。

有人说,iText(夏普)开发人员非常清楚(由于提出了许多这样的问题)

  • iText(夏普)用户可能有权在没有所有者密码的情况下执行此类操作,因为前面提到的文档加密字典中指定的用户访问权限,
  • 有无数的PDF,他们各自的所有者应用了所有者密码(以防止被他人滥用),然后忘记它(或通过使用随机生成的一个从来不知道它开始),和
  • iText(夏普)(开源)可以很容易地被任何人修补,不要尊重用户和所有者密码之间的差异。

为了允许用户执行他们有权使用的内容并防止扩展修补的库副本,iText(Sharp)在PdfReader类中包含对此测试的覆盖:

 /** * The iText developers are not responsible if you decide to change the * value of this static parameter. * @since 5.0.2 */ public static bool unethicalreading = false; 

因此,通过设置

 PdfReader.unethicalreading = true; 

全局覆盖此权限检查机制。

请尊重PDF作者的权利,如果您确实有权执行相关操作,请仅使用此覆盖。

我应用此解决方法,它的工作原理:

 private void fixIssue(PdfReader pdfReader) throws Exception { Field f = pdfReader.getClass().getDeclaredField("ownerPasswordUsed"); f.setAccessible(true); f.setBoolean(pdfReader, true); }