生成的签名PDF会导致Adobe Reader崩溃但没有其他PDF阅读器

问题描述:

我们有修改PDF然后数字签名修改过的PDF的代码。我们使用iTextSharp库的LGPL版本(4.1.6)对PDF进行数字签名。生成的签名PDF会导致Adobe Reader崩溃但没有其他PDF阅读器

public static Stream DigitallyCertifyPdfStream(Stream uncertifiedFileStream, CertificationBundle certificationBundle) 
{ 
    using (var memoryStream = new MemoryStream()) 
    { 
     var pdfReader = new PdfReader(uncertifiedFileStream); 
     var signatureStamper = PdfStamper.CreateSignature(pdfReader, memoryStream, '\0', null); 
     signatureStamper.SetEncryption(null, Encoding.UTF8.GetBytes(certificationBundle.Password), PdfWriter.ALLOW_PRINTING | PdfWriter.ALLOW_MODIFY_ANNOTATIONS, PdfWriter.STANDARD_ENCRYPTION_128); 

     var signatureAppearance = signatureStamper.SignatureAppearance; 
     signatureAppearance.Reason = "Approval of design"; 
     signatureAppearance.Location = ""; 

     var privateKey = certificationBundle.PrivateKey; 
     var signingCertificates = new[] { certificationBundle.Certificate }; 
     signatureAppearance.SetCrypto(privateKey, signingCertificates, null, PdfSignatureAppearance.WINCER_SIGNED); 

     pdfReader.Close(); 
     signatureStamper.Close(); 

     return new MemoryStream(memoryStream.ToArray()); 
    } 
} 

下面是一个示例PDF,它展示了这个问题。 PDF将首先打开,但然后冻结,无法导航。无论您是否有我们的证书来验证安装的签名,问题似乎都会发生。

此问题似乎并不一致,并且问题仅在Adobe Reader中存在。浏览器PDF阅读器和福昕阅读器(它的签名验证)处理它就好了。有时会出现一个错误框,表示“打开流时出错”。

的另外的兴趣,对已通过与此相同的数字签名历程的PDF文件,我们已经观察到外观完整性报告

Adobe Appearance Integrity Report

目前,我们是不确定的,如果这些都涉及到以下问题。我提到他们是因为他们可能是相关的。

问题是,为什么数字签名的PDF会使Adobe Reader崩溃,我们该如何解决它?

+0

我希望签名应用程序的用户知道您正在创建的签名已被弃用(不再在PDF 2.0中有效)并且不安全。您创建不安全签名的用例是什么? –

+0

欲了解更多信息:http://itextpdf.com/blog/are-pdf-signatures-shattered(您正在使用SHA-1)。拥有某种处理能力的任何人都可以在不破坏签名的情况下更改PDF –

+0

@BrunoLowagie那么iTextSharp的LGPL版本不能创建安全签名是真的吗?我在加密算法中看到的选项是'PdfWriter.STANDARD_ENCRYPTION_128','PdfWriter.ENCRYPTION_AES_128'和'PdfWriter.STANDARD_ENCRYPTION_40'。目前的iTextSharp发行版使用什么加密算法? –

你的PDF文件包含一个断开的图像:

16 0 obj 
<</Type/XObject/BitsPerComponent 8/Interpolate true/Width 736/ColorSpace/DeviceRGB/Filter/DCTDecode/Length 0/Height 1242/Subtype/Image>>stream 

endstream 
endobj 

这个影像x对象声称包含的RGB位图图像(736x1242,24位),并在同一时间是空的(长度 0)。如果遇到这种缺少的数据,PDF查看器可能会失败(尽管Adobe Reader锁定一段时间令人印象深刻......)。

请检查您的源PDF中的流是否已损坏。


一个问题的方式:

pdfReader.Close(); 
    signatureStamper.Close(); 

您关闭压模之前关闭的读者。由于压模可能需要在关闭过程中访问读者,这是一个坏主意。只需切换Close调用的顺序。


顺便问一下,你的代码产生adbe.pkcs7.sha1签名。这在安全方面是一个糟糕的想法,因为无论您使用哪种安全算法签名,此机制都将SHA1用于第一个文档散列,否则SHA1通常不再被认为是安全的。

+0

所以......关于这方面的更多注意事项。 @mkl ...对于你提到的XObject而言,事实上它的长度为零。流是空的,但你看,它有一个宽度和高度等,这是不好的。我认为这是破坏了签名的外观,这就是挂在Adobe浏览器上的东西。福昕实际上是在忽略它的外观,虽然打开文档可能是期望的行为,但这并不好。基于浏览器的观众只是简单地展示了这个外观......这也不是很好。 – joelgeraci

+0

是的,在同一时间空荡荡的,并包含一个大的图像......;) – mkl

+0

触摸 - 我想我爱你。 – joelgeraci