Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在iTextSharp中对PDF签名后隐藏有效性未知符号_C#_.net_Pdf_Itext_Digital Signature - Fatal编程技术网

C# 如何在iTextSharp中对PDF签名后隐藏有效性未知符号

C# 如何在iTextSharp中对PDF签名后隐藏有效性未知符号,c#,.net,pdf,itext,digital-signature,C#,.net,Pdf,Itext,Digital Signature,我在C.Net中使用iTextSharp创建了一个签名PDF。 在签名的PDF中,我希望有一个有效性符号,这样当用户在AdobeReader中打开它时,它会显示一个绿色的勾号及其签名 但在我的web应用程序中,一个带有画布的html页面,我想从PDF中删除该问号,这样它就不会显示在该屏幕中: 所以我想保留PDF的原始字节,其中signatureappearance.Acro6Layers=false;添加到代码中以获取此符号。但在使用画布在我的查看器html页面中显示它之前,我想修改字节并删除

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

但在我的web应用程序中,一个带有画布的html页面,我想从PDF中删除该问号,这样它就不会显示在该屏幕中:


所以我想保留PDF的原始字节,其中signatureappearance.Acro6Layers=false;添加到代码中以获取此符号。但在使用画布在我的查看器html页面中显示它之前,我想修改字节并删除此黄色标记,以便它不会显示未验证的签名。

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

由于Acrobat 6之前的附加层都是在保存的文件中以签名外观绘制的,因此必须清除它们。您可以这样做:

using (PdfReader pdfReader = new PdfReader(source))
using (PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(dest, FileMode.Create, FileAccess.Write), '\0', 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);
        }
    }
}
在不同的渲染器中,原始示例文档和由上述代码生成的文档的签名外观如下所示:

我使用的是Chrome的原样渲染器:

Acrobat 9.5德语地区不信任您的发卡机构

Acrobat DC信任您的发卡机构


不过,有一点要警告:如果文档中有认证签名,而不仅仅是批准签名,特别是不允许更改的认证签名,Acrobat很可能不会喜欢结果。

请分享一个具有代表性的示例PDF。此外,您的web应用程序如何准确地显示PDF?它是否将PDF显示委托给浏览器,以便根据浏览器的不同,在页面中嵌入一些内置或外部PDF查看组件?或者它是否带来了一个基于JavaScript的查看器并使用它?还是将PDF渲染为位图服务器端并显示这些图像?还是另一种方法?@mkl,我们正在使用Aspose将pdf转换为分页图像,然后在浏览器画布上显示为图像。这是类似pdf的链接:在我将pdf转换为图像之前,我只想删除签名有效性符号,并具有下载选项的有效性。因此,它将有助于用户体验,就像预览时显示签名无效一样,因此用户会感到困惑。@mkl,关于这方面的任何建议,我在这个问题中引用了您的ans:-但它改变了外观,我只想改变signatureappearance.Acro6Layers=true;所以签名有效性符号消失了。如果您有任何建议,我们将不胜感激。您可以创建两个版本,一个是“官方”PDF,另一个是“预览”PDF,Acro6Layers=true供您查看。是的,但这些是来自第三方服务全球签名DSS的云签名,如果我这样做,将花费我/用户两倍的费用,这是我们不想要的。
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);
    }
}