Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.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# 4.0 使用iText 7以非ASCII字符打开受密码保护的PDF文件_C# 4.0_Itext7 - Fatal编程技术网

C# 4.0 使用iText 7以非ASCII字符打开受密码保护的PDF文件

C# 4.0 使用iText 7以非ASCII字符打开受密码保护的PDF文件,c#-4.0,itext7,C# 4.0,Itext7,我在Dot Net 4/C#项目中使用iText 7(7.1.7版),处理具有用户密码的PDF文档 密码是补充的,除了在密码中使用非ASCII字符(如符号)外,一切都正常工作 有人知道如何让iText 7理解像“hello£1234”这样的密码吗 我曾尝试通过将字符串视为UTF8或Unicode来提取密码字节,但似乎没有任何效果 在尝试加载PdfDocument时,我只得到一个“坏用户密码”异常 这是我的密码: string password = "hello£1234"; byte[] pas

我在Dot Net 4/C#项目中使用iText 7(7.1.7版),处理具有用户密码的PDF文档

密码是补充的,除了在密码中使用非ASCII字符(如符号)外,一切都正常工作

有人知道如何让iText 7理解像“hello£1234”这样的密码吗

我曾尝试通过将字符串视为UTF8或Unicode来提取密码字节,但似乎没有任何效果

在尝试加载PdfDocument时,我只得到一个“坏用户密码”异常

这是我的密码:

string password = "hello£1234";
byte[] passwordBytes = new System.Text.ASCIIEncoding().GetBytes(password);
PdfReader reader = new PdfReader(tempInFile, new ReaderProperties().SetPassword(passwordBytes));
PdfDocument pdfDoc = new PdfDocument(reader);
// Do my stuff with the document here
pdfDoc.Close();

我以为我已经在使用系统的默认代码页中找到了答案,但结果并不是100%有效

普通ASCII不能表示%这样的字符,但扩展ASCII(或代码页437)可以。UTF8也可以,但不同类型的编码似乎在不同的环境下工作

目前,我的解决方案只是尝试一些。这是一个有点像撞锤的方法,所以如果有人有一个更优雅的解决方案,那么我很有兴趣去看看

这是我现在的代码:

Encoding cp437 = Encoding.GetEncoding(437);
List<byte[]> passwordByteList = new List<byte[]>()
{
    Encoding.Default.GetBytes(password),   //Default codepage
    Encoding.UTF8.GetBytes(password),  //UTF8 encoding
    cp437.GetBytes(password),  //Code page 437 (extended ASCII) encoding
};

foreach(byte[] passwordBytes in passwordByteList)
{
    PdfReader reader = new PdfReader(tempInFile, new ReaderProperties().SetPassword(passwordBytes));
    try
    {
        //Try to open the PDF with the password 
        PdfDocument pdfDoc = new PdfDocument(reader);

        //Do something with the document
        pdfDoc.Close();
        reader.Close();
   }
   catch (Exception ex)
   {
       System.Diagnostics.Debug.WriteLine(ex.ToString());
       //Exception thrown by PDF reader. We need to try the next password.
       reader.Close();
   }
}
Encoding cp437=Encoding.GetEncoding(437);
列表密码Bytelist=新列表()
{
Encoding.Default.GetBytes(密码),//默认代码页
Encoding.UTF8.GetBytes(密码),//UTF8编码
GetBytes(密码),//代码页437(扩展ASCII)编码
};
foreach(passwordByteList中的byte[]passwordBytes)
{
PdfReader reader=new PdfReader(tempinfle,new ReaderProperties().SetPassword(passwordBytes));
尝试
{
//尝试用密码打开PDF
PdfDocument pdfDoc=新PdfDocument(读卡器);
//对文档做些什么
pdfDoc.Close();
reader.Close();
}
捕获(例外情况除外)
{
System.Diagnostics.Debug.WriteLine(例如ToString());
//PDF阅读器引发异常。我们需要尝试下一个密码。
reader.Close();
}
}

我以为我在使用系统的默认代码页时找到了答案,但结果并不是100%有效

普通ASCII不能表示%这样的字符,但扩展ASCII(或代码页437)可以。UTF8也可以,但不同类型的编码似乎在不同的环境下工作

目前,我的解决方案只是尝试一些。这是一个有点像撞锤的方法,所以如果有人有一个更优雅的解决方案,那么我很有兴趣去看看

这是我现在的代码:

Encoding cp437 = Encoding.GetEncoding(437);
List<byte[]> passwordByteList = new List<byte[]>()
{
    Encoding.Default.GetBytes(password),   //Default codepage
    Encoding.UTF8.GetBytes(password),  //UTF8 encoding
    cp437.GetBytes(password),  //Code page 437 (extended ASCII) encoding
};

foreach(byte[] passwordBytes in passwordByteList)
{
    PdfReader reader = new PdfReader(tempInFile, new ReaderProperties().SetPassword(passwordBytes));
    try
    {
        //Try to open the PDF with the password 
        PdfDocument pdfDoc = new PdfDocument(reader);

        //Do something with the document
        pdfDoc.Close();
        reader.Close();
   }
   catch (Exception ex)
   {
       System.Diagnostics.Debug.WriteLine(ex.ToString());
       //Exception thrown by PDF reader. We need to try the next password.
       reader.Close();
   }
}
Encoding cp437=Encoding.GetEncoding(437);
列表密码Bytelist=新列表()
{
Encoding.Default.GetBytes(密码),//默认代码页
Encoding.UTF8.GetBytes(密码),//UTF8编码
GetBytes(密码),//代码页437(扩展ASCII)编码
};
foreach(passwordByteList中的byte[]passwordBytes)
{
PdfReader reader=new PdfReader(tempinfle,new ReaderProperties().SetPassword(passwordBytes));
尝试
{
//尝试用密码打开PDF
PdfDocument pdfDoc=新PdfDocument(读卡器);
//对文档做些什么
pdfDoc.Close();
reader.Close();
}
捕获(例外情况除外)
{
System.Diagnostics.Debug.WriteLine(例如ToString());
//PDF阅读器引发异常。我们需要尝试下一个密码。
reader.Close();
}
}

您是否尝试使用Encoding.GetEncoding(1252)


我发现它通常包含大多数字符

您是否尝试使用Encoding.GetEncoding(1252)


我发现它通常包含大多数字符

实际上,这取决于用于加密试图打开的PDF的安全处理程序的版本

ISO 32000-2规定:

第6版的所有密码应基于Unicode。用户提供密码的预处理首先包括通过使用Normalize和BiDi选项将“stringprep”算法(互联网RFC 3454)的“SASLPrep”配置文件(互联网RFC 4013)应用于所提供的密码来规范其表示。接下来,应将密码字符串转换为UTF-8编码,如果字符串长度超过127字节,则将其截断为前127字节(参见7.6.4.3.2,“算法2.A:从加密文档中检索加密密钥以对其进行解密(版本6及更高版本)”,步骤(A,b))

对于其他修订版,这没有指定,取决于安全处理程序的实现

因此,对于修订版6,您正确地应用了UTF-8编码,但没有进行规范化准备。在简单的情况下,规范化不会更改密码,因此您的代码通常会成功


对于其他修订,您的方法与任何修订一样好;)

实际上,这取决于用于加密试图打开的PDF的安全处理程序的版本

ISO 32000-2规定:

第6版的所有密码应基于Unicode。用户提供密码的预处理首先包括通过使用Normalize和BiDi选项将“stringprep”算法(互联网RFC 3454)的“SASLPrep”配置文件(互联网RFC 4013)应用于所提供的密码来规范其表示。接下来,应将密码字符串转换为UTF-8编码,如果字符串长度超过127字节,则将其截断为前127字节(参见7.6.4.3.2,“算法2.A:从加密文档中检索加密密钥以对其进行解密(版本6及更高版本)”,步骤(A,b))

对于其他修订版,这没有指定,取决于安全处理程序的实现

因此,对于修订版6,您正确地应用了UTF-8编码,但没有进行规范化准备。在简单的情况下,规范化不会更改密码,因此您的代码通常会成功

对于其他修订,您的方法与任何修订一样好;)