ITextSharp Bug? - Null reference when stamping certificate protected pdf

雨燕双飞 提交于 2019-12-24 23:32:48

问题


I'm using ITextSharp's PdfStamper to fill in a pdf form.

This works for unprotected and password protected Pdfs, but certificate protected PDFs cause a null reference exception when calling PdfStamper.Close().

Has anyone come across this before?

Example failing program:

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()));
        }
    }
}

Exception stacktrace:

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

Exception is only thrown if the stamper is opened in append mode. But not using append mode removes the original protection, which I need to preserve.

ITextSharp is version 5.5.4 from Nuget stable.


回答1:


This iText issue has been resolved in version 5.5.12.

The relevant git check-in is d9aede3 dated March 31st, 2017, and has the comment "Fix exception when signing a document that is encrypted with certificate. Suggested by https://github.com/MADzO". This "signing" actually is a special case of arbitrary stamping while keeping the certificate protection intact.

The fix was to add the original document ID of the loaded PDF to the PdfEncryption object (which holds the encryption related information) in case of certificate encryption, too, not only in case of password encryption as before.

The PdfEncryption class expects its documentID member to be set as encrypted documents must have an ID. As that member was not set in the cases at hand, the NullReferenceException occurred.


Tested with the current iTextSharp 5.5.14-SNAPSHOT development version. Verified by undoing and redoing the above-mentioned fix.

Tested using test data provided by user JC1001 in a comment to his question iTextSharp object reference error on PdfStamper for certificate-protected file.



来源:https://stackoverflow.com/questions/27897744/itextsharp-bug-null-reference-when-stamping-certificate-protected-pdf

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!