iTextSharp 5/iText8 PDF密码保护失效问题排查与解决
PDF密码保护未生效问题及解决
问题现象
使用iTextSharp 5为已有PDF文件设置密码保护后,生成的文件在Microsoft Edge中无需输入密码即可直接打开,密码保护功能未生效。
iTextSharp 5 实现代码
public void PasswordProtectPDF(string source, string destionation, string pass) { using (Stream input = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (Stream output = new FileStream(destionation, FileMode.Create, FileAccess.Write, FileShare.None)) { PdfReader reader = new PdfReader(input); PdfReader.unethicalreading = true; PdfEncryptor.Encrypt(reader, output, true, null, pass, PdfWriter.ALLOW_SCREENREADERS); } } }
升级iText 8后问题仍存在
更换为iText 8后,问题依旧——生成的PDF无需密码即可打开,对应代码如下:
iText 8 实现代码
public void PasswordProtectPDF(string source, string destionation, string pass) { using (Stream input = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (Stream output = new FileStream(destionation, FileMode.Create, FileAccess.Write, FileShare.None)) { PdfReader reader = new PdfReader(input); reader.SetUnethicalReading(true); EncryptionProperties encryptionProperties = new EncryptionProperties(); encryptionProperties.SetStandardEncryption(null, Encoding.ASCII.GetBytes(pass), EncryptionConstants.ALLOW_PRINTING, EncryptionConstants.STANDARD_ENCRYPTION_128); PdfEncryptor.Encrypt(reader, output, encryptionProperties); } } }
解决方法
修改iText 8代码中的SetStandardEncryption方法参数顺序即可解决:
encryptionProperties.SetStandardEncryption(Encoding.ASCII.GetBytes(pass), null, EncryptionConstants.ALLOW_PRINTING, EncryptionConstants.STANDARD_ENCRYPTION_128);
问题根源
iText的SetStandardEncryption方法参数定义为:第一个参数是用户密码(打开PDF需验证的密码),第二个参数是所有者密码(用于修改PDF权限)。之前的代码将用户密码设为null,仅设置了所有者密码,这意味着任何人都可以无密码打开PDF,仅限制修改操作。调整参数顺序后,正确设置了用户密码,打开PDF时就会触发密码验证。
内容的提问来源于stack exchange,提问作者Frank Martin
相关产品推荐
相关产品推荐

