如何在 iTextSharp 中签署 PDF 后隐藏有效性未知符号

How to hide Validity unknown symbol after signing the PDF in iTextSharp

我在 C# .Net 中使用 iTextSharp 创建了签名 PDF。 在签名的 PDF 中,我希望有一个有效性符号,以便当用户在 Adob​​e Reader 中打开它时,它会显示一个绿色的勾号及其签名。

但是在我的网络应用程序中(html 页面 canvas)我想从 PDF 中删除那个问号,这样它就不会像这个屏幕那样显示:

所以我想保留 PDF 的原始字节,其中在代码中添加了 signatureappearance.Acro6Layers = false; 以获取此符号。但是在我的查看器中显示它之前(html 页面 canvas)我想修改字节并删除这个黄色标记,这样它就不会显示 "Signature Not Verified".

我没有使用 Aspose PDF 到图像的渲染经验,但看起来它可能只是渲染 PDF 中的签名外观。顺便说一句,这才是正确的做法。

由于Acrobat 6之前多出的图层都是在保存文件的签名外观中绘制的,所以需要清除掉。你可以这样做:

using (PdfReader pdfReader = new PdfReader(source))
using (PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(dest, FileMode.Create, FileAccess.Write), '[=10=]', true))
{
    AcroFields fields = pdfStamper.AcroFields;
    List<string> names = fields.GetSignatureNames();
    foreach (string name in names)
    {
        PdfDictionary normal = PdfReader.GetPdfObject(fields.GetNormalAppearance(name)) as PdfDictionary;
        PdfDictionary frm = normal?.GetAsDict(PdfName.RESOURCES)?.GetAsDict(PdfName.XOBJECT)?.GetAsStream(PdfName.FRM);
        PdfDictionary frmResources = frm?.GetAsDict(PdfName.RESOURCES);
        PdfDictionary frmXobjectResources = frmResources?.GetAsDict(PdfName.XOBJECT);
        if (frmXobjectResources != null)
        {
            Console.WriteLine("Found XObject resources of FRM XObject");
            clearLayer(pdfStamper.Writer, frmXobjectResources, PdfName.N1);
            clearLayer(pdfStamper.Writer, frmXobjectResources, PdfName.N3);
            clearLayer(pdfStamper.Writer, frmXobjectResources, PdfName.N4);
            pdfStamper.MarkUsed(frmXobjectResources);
            pdfStamper.MarkUsed(frmResources);
            pdfStamper.MarkUsed(frm);
        }
    }
}

使用这个辅助方法:

void clearLayer(PdfWriter writer, PdfDictionary frmXobjectResources, PdfName layerName)
{
    PdfStream existingLayer = frmXobjectResources.GetAsStream(layerName);
    if (existingLayer != null)
    {
        PdfArray bBox = existingLayer.GetAsArray(PdfName.BBOX);
        PdfTemplate newLayer = PdfTemplate.CreateTemplate(writer, 0, 0);
        newLayer.BoundingBox = PdfReader.GetNormalizedRectangle(bBox);
        frmXobjectResources.Put(layerName, newLayer.IndirectReference);
    }
}

在不同的渲染器中,原始示例文档的签名外观和上述代码生成的文档如下所示:

  • 一个"as is"渲染器(我使用了Chrome):

  • Acrobat 9.5(德语语言环境)不信任您的发行者

  • Acrobat DC 信任您的颁发者

但请注意:如果文档带有认证签名,而不仅仅是批准签名,尤其是带有不允许更改的认证签名,Acrobat 很可能不会喜欢结果。