adobeacrobatreader和Foxit Reader显示PDF签名有效,但iText7显示相反



我有一个客户端签名的PDF文件,其中包含两个签名,并且在使用adobeacrobat Reader和Foxit Reader打开时完全有效。但我使用iText7 (c#)来验证这些签名,并在验证第二个签名时获得false。

下面是我的代码:
public static async Task VefifySignaturePDFFile(Stream mStream)
{
try
{
using (iText.Kernel.Pdf.PdfReader pdfReader = new iText.Kernel.Pdf.PdfReader(mStream, new iText.Kernel.Pdf.ReaderProperties()))
{
using (var oStream = new MemoryStream())
{
using (iText.Kernel.Pdf.PdfDocument pdfDocument = new iText.Kernel.Pdf.PdfDocument(pdfReader))
{
iText.Signatures.SignatureUtil signatureUtil = new iText.Signatures.SignatureUtil(pdfDocument);
iText.Forms.PdfAcroForm acroForm = iText.Forms.PdfAcroForm.GetAcroForm(pdfDocument, false);
if (signatureUtil.GetSignatureNames().Count > 0)
{
foreach (String name in signatureUtil.GetSignatureNames())
{
#region Kiểm tra chữ ký trong file
iText.Signatures.PdfPKCS7 pkcs7 = null;
var sig = signatureUtil.GetSignature(name);
var cover = signatureUtil.SignatureCoversWholeDocument(name);
var llX = float.Parse(acroForm.GetFormFields()[name].GetWidgets().First().GetRectangle().Get(0).ToString());
var llY = float.Parse(acroForm.GetFormFields()[name].GetWidgets().First().GetRectangle().Get(1).ToString());
var urX = float.Parse(acroForm.GetFormFields()[name].GetWidgets().First().GetRectangle().Get(2).ToString()) - llX;
var urY = float.Parse(acroForm.GetFormFields()[name].GetWidgets().First().GetRectangle().Get(3).ToString()) - llY;
var page = pdfDocument.GetPageNumber(acroForm.GetFormFields()[name].GetWidgets().First().GetPage());
var reason = sig.GetReason();
try
{
pkcs7 = signatureUtil.ReadSignatureData(name); // Chữ ký bị lỗi thì sẽ nhẩy vào ex
}
catch (Exception ex)
{
continue;
}
var verify = pkcs7.VerifySignatureIntegrityAndAuthenticity(); // Tài liệu bị thay đổi sẽ ra false
#endregion
}
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}

有人知道我在这里做错了什么吗?

第二个签名有一个问题:它的嵌入式CMS签名容器有这个EncapsulatedContentInfo条目:

SEQUENCE (2 elem)
OBJECT IDENTIFIER 1.2.840.113549.1.7.1 data (PKCS #7)
[0] (1 elem)
OCTET STRING (0 byte)

特别地,这个表项有一个eContent值,0标记的OCTET STRING (0 byte),即一个长度为0的字节数组。

根据RFC 3852和RFC 5652 (PDF规范ISO 32000-1和ISO 32000-2分别引用为CMS规范),eContent-如果存在-包含签名数据。只有当eContent不存在时,签名的数据才在CMS容器之外。

因此,严格地说,您的第二个签名声明它签名的是一个空字节数组,而不是嵌入其中的PDF文档。

您提到adobeacrobat和Foxit验证签名。显然,这些验证器忽略了具有误导性的eContent条目,可能是因为包含的字节数组是空的。另一方面,iText和eSig DSS严格遵循rfc,在它们的验证例程中考虑eContent条目,因此必然会遇到验证失败。

最新更新