C# 伊特夏普虫子为受证书保护的pdf加盖戳记时的空引用
我正在使用C# 伊特夏普虫子为受证书保护的pdf加盖戳记时的空引用,c#,itextsharp,C#,Itextsharp,我正在使用ITextSharp的PdfStamper来填写pdf表单 这适用于未受保护和密码保护的PDF,但受证书保护的PDF在调用PdfStamper.Close()时会导致null引用异常 以前有人见过这个吗 失败程序示例: using System.Security.Cryptography.X509Certificates; using iTextSharp.text; using iTextSharp.text.pdf; using System.IO; using Org.Bounc
ITextSharp的
PdfStamper来填写pdf表单
这适用于未受保护和密码保护的PDF,但受证书保护的PDF在调用PdfStamper.Close()
时会导致null引用异常
以前有人见过这个吗
失败程序示例:
using System.Security.Cryptography.X509Certificates;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.IO;
using Org.BouncyCastle.Crypto;
using X509Certificate = Org.BouncyCastle.X509.X509Certificate;
namespace ITextError
{
class Program
{
static X509Certificate2 certificate = new X509Certificate2(@"certificate.pfx","password",X509KeyStorageFlags.Exportable);
static X509Certificate bouncyCertficate = Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(certificate);
static AsymmetricCipherKeyPair keyPair = Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair(certificate.PrivateKey);
public static byte[] CreatePdf()
{
using (MemoryStream ms = new MemoryStream())
{
using (Document document = new Document())
{
var writer=PdfWriter.GetInstance(document, ms);
writer.SetEncryption(new X509Certificate[]{bouncyCertficate},
new int[]{PdfWriter.ALLOW_MODIFY_CONTENTS},
PdfWriter.STANDARD_ENCRYPTION_128
);
document.Open();
document.Add(new Paragraph("Hello World"));
}
return ms.ToArray();
}
}
public static byte[] StampPdf(byte[] src)
{
File.WriteAllBytes("tmp.pdf",src);
PdfReader reader = new PdfReader("tmp.pdf",bouncyCertficate,keyPair.Private);
using (MemoryStream ms = new MemoryStream())
{
using (PdfStamper stamper = new PdfStamper(reader, ms,reader.PdfVersion,true))
{
PdfContentByte canvas = stamper.GetOverContent(1);
ColumnText.ShowTextAligned(canvas, Element.ALIGN_LEFT, new Phrase("Hello people!"), 36, 540, 0);
stamper.Close();
}
return ms.ToArray();
}
}
static void Main(string[] args)
{
File.WriteAllBytes(@"output.pdf",StampPdf(CreatePdf()));
}
}
}
异常堆栈跟踪:
Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
at iTextSharp.text.pdf.PdfEncryption.CreateInfoId(Byte[] id, Boolean modified)
at iTextSharp.text.pdf.PdfEncryption.GetFileID(Boolean modified)
at iTextSharp.text.pdf.PdfStamperImp.Close(PdfIndirectReference info, Int32 s kipInfo)
at iTextSharp.text.pdf.PdfStamperImp.Close(IDictionary`2 moreInfo)
at iTextSharp.text.pdf.PdfStamper.Close()
at ITextError.Program.StampPdf(Byte[] src) in Program.cs:line 45
at ITextError.Program.Main(String[] args) in Program.cs:line 53
只有在附加模式下打开母版时才会引发异常。
但不使用附加模式会删除我需要保留的原始保护
ITextSharp是Nuget stable的5.5.4版。此iText问题已在5.5.12版中解决
相关git签入日期为2017年3月31日的D9AED3,注释为“签署使用证书加密的文档时修复异常。建议”。这种“签名”实际上是一种特殊情况,即在保持证书保护完好无损的情况下任意加盖印章
修复方法是在证书加密的情况下,将加载的PDF的原始文档ID添加到PdfEncryption
对象(该对象保存与加密相关的信息),而不仅仅是在以前的密码加密的情况下
PdfEncryption
类要求将其documentID
成员设置为加密文档必须具有ID。由于该成员未在手头的案例中设置,因此发生了NullReferenceException
异常
使用当前的iTextSharp 5.5.14-SNAPSHOT开发版本进行测试。通过撤消并重新执行上述修复来验证
使用用户在对其问题的评论中提供的测试。请提供堆栈跟踪并指明您正在使用的库版本。您是否拥有与用于保护PDF的公钥相对应的私钥?如果不是,那就不是虫子,而是预防措施。另外:当文件受密码保护时,如果不使用所有者密码或不道德的阅读
,您将无法填写表单。如果是,则使用的是过时的iText版本。已编辑为包含失败代码和堆栈跟踪。我确实有私钥,但如果这是一个预防措施,它不应该抛出一个更友好的异常吗?