Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用iTextSharp打开受密码保护的pdf文件_C#_Asp.net_Pdf_Passwords_Itextsharp - Fatal编程技术网

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

C# 使用iTextSharp打开受密码保护的pdf文件,c#,asp.net,pdf,passwords,itextsharp,C#,Asp.net,Pdf,Passwords,Itextsharp,我正在制作一个应用程序,它应该显示带有密码的PDF文件。这是我的代码: protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { try { string filePath = Request.QueryString["filePath"]; if (filePath.ToUpper().EndsWit

我正在制作一个应用程序,它应该显示带有密码的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 = "<script language='Javascript'>alert('File Not Found! Call Records Department for verification. ')</script>";
            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();
    }
}
受保护的无效页面加载(对象发送方,事件参数e)
{
如果(!Page.IsPostBack)
{
尝试
{
字符串filePath=Request.QueryString[“filePath”];
if(filePath.ToUpper().EndsWith(“PDF”))
{
copyPDF(文件路径);
}
}
抓住
{
string message=“警报('未找到文件!请致电记录部门进行验证')”;
ScriptManager.RegisterStartupScript(第页,this.GetType(),消息,消息,false);
}
}
}
公共void copyPDF(字符串文件路径)
{
iTextSharp.text.pdf.RandomAccessFileOrArray ra=new iTextSharp.text.pdf.RandomAccessFileOrArray(Server.MapPath(ResolveUrl(filePath));
如果(ra!=null)
{
System.IO.MemoryStream ms=新的System.IO.MemoryStream();
byte[]password=System.Text.ASCIIEncoding.ASCII.GetBytes(“Secretinfo”);
iTextSharp.text.pdf.PdfReader thepdfReader=新的iTextSharp.text.pdf.PdfReader(ra,密码);
int pages=thepdfreeader.NumberOfPages;
iTextSharp.text.Document pdfDoc=新的iTextSharp.text.Document();
iTextSharp.text.pdf.PdfCopy PdfCopy=新iTextSharp.text.pdf.PdfCopy(pdfDoc,ms);
pdfDoc.Open();
int i=0;
while(i
我的代码在没有密码的情况下打开pdf文件没有问题,但即使提供了密码,也无法使用密码打开pdf文件。应用程序执行捕获。我的代码有什么问题

编辑: 我删除了捕获以查看抛出的异常

异常详细信息: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:    }
第49行:while(i
对于加密文档的某些操作,iText(Sharp)要求不仅使用用户密码打开文档,而且使用所有者密码打开文档。这与PDF规范中这些密码的定义相对应:

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

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

iText(Sharp)目前没有详细检查文档加密字典中指定的用户访问权限,但对于需要特定权限的操作,总是需要所有者密码,而从文档复制整个页面就是其中之一

尽管如此,iText(Sharp)开发人员非常清楚(由于提出了许多这样的问题)

  • iText(Sharp)用户可能有权执行此类操作,即使没有所有者密码,因为在文档的加密字典中指定了上述用户访问权限
  • 有无数的PDF,其各自的所有者对其应用了所有者密码(以防止他人滥用),然后忘记了它(或者使用随机生成的一个从一开始就不知道的密码),以及
  • 任何人都可以轻松地修补iText(Sharp)(开源)以避免用户和所有者密码之间的差异
为了允许用户做他们有权做的事情,并防止库的修补副本传播,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);

}

尝试使用此解决方法解锁受保护的PdfReader。这是我的工作:

public static PdfReader TryToUnlockPdf(PdfReader reader)
{
    if (reader == null)
    {
        return reader;
    }
    try
    {
        var f = reader.GetType().GetField("encrypted", BindingFlags.NonPublic | BindingFlags.Instance);
        f?.SetValue(reader, false);
    }
    catch (Exception)
    { // ignore
    }
    return reader;
}

private static void GetPdfPageFiles(this Page pageFile)
{
    reader = new PdfReader(pageFile.ContentBytes);
    // Unlock protected 
    reader = TryToUnlockPdf(reader);

    // if no using TryToUnlockPdf workaroud - GetImportedPage method raises "System.ArgumentException: PdfReader not opened with owner password"
    var curPage = pdfWriter.GetImportedPage(reader, 0);
}

引发了哪个异常?它不会引发异常。它执行catch语句,在本例中,该语句是一个弹出窗口,显示“未找到文件!”!打电话给记录部门进行验证。'hey@mkl我删除了捕获,以了解引发的异常类型,它显示System.ArgumentException:PdfReader未使用所有者密码打开。似乎您没有提供正确的密码。可能PDF既有用户密码,也有所有者密码,而您只提供了用户密码。我使用了现在我收到一个InvalidCastException错误,无法将类型为“iTextSharp.text.pdf.PdfArray”的对象强制转换为类型为“iTextSharp.text.pdf.PRIndirectReference”。然后您的pdf或itext出现错误。你能提供PDF进行分析吗?我怎样才能提供给你PDF?(对不起,如果你告诉我怎么做我会非常乐意。)Stackoverflow本身没有文件交换服务。因此,当我