0
votes

I have created a signed PDF using iTextSharp in C# .Net. In the signed PDF I want to have a validity symbol so that when a user opens it in Adobe Reader it shows a green tick mark along with its signature.

But in my web application (a html page with canvas) I want to remove that question mark from the PDF so that it does not show like in this screen: enter image description here

So I want to keep the original bytes of the PDF in which signatureappearance.Acro6Layers = false; is added in code to get this symbol. But before showing it in my viewer (html page with canvas) I want to modify bytes and remove this yellow mark, so that it does not show "Signature Not Verified".

1
Please also share a representative example PDF. Furthermore, how exactly does your web application display the PDF? Does it delegate the PDF displaying to the browser (so that depending on the browser some built-in or some external PDF viewing component is embedded in your page)? Or does it bring a JavaScript based viewer along and uses it? Or does it render the PDF as bitmaps server side and display those images? Or yet a different approach?mkl
@mkl, we are using Aspose to convert pdf to paging wise images then show as image on browser canvas. This is link to similar pdf : gofile.io/d/2KNAky I just want to remove signature validity symbol before I convert my pdf to image and have actual pdf with validity for download option. So it will good for user experience as if on preview it shows signature invalid so user gets confuse.Urmi_VV_Developer
@mkl, Any suggestions on this I referred this your ans in this question : stackoverflow.com/questions/55964130/… - But it changes appearance I just want to change signatureappearance.Acro6Layers = true; so that signature validity symbol disappears. Any suggestions would be highly appreciated.Urmi_VV_Developer
You could create two versions, an 'official' PDF and a 'preview' PDF (with Acro6Layers=true) for your viewer.yacc
yes but these are cloud signatures from 3rd party services Global sign DSS and If i do that it will cost me/User twice, which we don't want.Urmi_VV_Developer

1 Answers

1
votes

I have no experiences with the Aspose PDF-to-image rendering, but it looks like it probably simply renders the signature appearance as it is in the PDF. This, by the way, would be the correct thing to do.

As the extra layers from before Acrobat 6 are all drawn in the signature appearance in the saved file, you have to clear them. You can do that like this:

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

with this helper method:

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

In different renderers the signature appearance of your original example document and the document resulting from the above code appear as follows:

  • an "as is" renderer (I used Chrome):

    Original-ChromeResult-Chrome

  • Acrobat 9.5 (German locale) not trusting your issuer

    Original-Acrobat9.5Result-Acrobat9.5

  • Acrobat DC trusting your issuer

    Original-AcrobatDcResult-AcrobatDc

A word of warning, though: In case of documents with certification signatures, not merely approval signatures, in particular with certification signatures with no changes allowed, Acrobat most likely will not like the result.