C# 4.0 使用iText 7以非ASCII字符打开受密码保护的PDF文件
我在Dot Net 4/C#项目中使用iText 7(7.1.7版),处理具有用户密码的PDF文档 密码是补充的,除了在密码中使用非ASCII字符(如符号)外,一切都正常工作 有人知道如何让iText 7理解像“hello£1234”这样的密码吗 我曾尝试通过将字符串视为UTF8或Unicode来提取密码字节,但似乎没有任何效果 在尝试加载PdfDocument时,我只得到一个“坏用户密码”异常 这是我的密码: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
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编码,但没有进行规范化准备。在简单的情况下,规范化不会更改密码,因此您的代码通常会成功 对于其他修订,您的方法与任何修订一样好;)