Signing existing

Skip Navigation LinksHome  /  Support  /  Forums  /  DynamicPDF CoreSuite for .NET (v8)  /  Re: Signing existing

DynamicPDF CoreSuite for .NET (v8) Forum

 Feb 04 2016 3:57 PM
I'm evaluating DynamicPDF for use in generating a PDF form which will include a signature block which will later be signed. The signature will be made with an X509 Certificate from a smart card.

I have been able to sign a document via the DynamicPDF Generator, but not add a signature to an existing document via the DynamicPDF Merger. In fact, if I add a signature during the initial generator processor, then later open the signed PDF to fill out a TextField in the form, the original signature is lost when the modified document is saved.

It seems the Merger doesn't play nice with signatures as a whole. If you generate a PDF with a signature field, save it, open it with the Merger and attempt to sign it, the signature is not found.

The following code snippet can reproduce what I'm talking about:

    void Main()
    {
        var lDestinationPath = @"C:\Temp\Sample.pdf";
        var lDestinationPathSigned = @"C:\Temp\Sample-Signed.pdf";
       
        const string lcTextFieldName = "textField1";
       
        const string lcSignatureFieldName = "MySigField1";
       
        var lSignatureField = new ceTe.DynamicPDF.PageElements.Forms.Signature(lcSignatureFieldName, 50, 200, 100, 30);
        lSignatureField.Font = Font.Helvetica;
       
        var lPage = new Page(PageSize.Letter);
        lPage.Elements.Add(lSignatureField);
       
        var lDocument = new Document();
        lDocument.Pages.Add(lPage);
        lDocument.Draw(lDestinationPath);
       
        var lSigningCertificate = GetSigningCertificate();
       
        var lPdfCertficate = new Certificate(lSigningCertificate);
        lPdfCertficate.SignSilently = false;
       
        var lMergeDocument = new MergeDocument(lDestinationPath);
        lMergeDocument.Sign(lcSignatureFieldName, lPdfCertficate);
        lMergeDocument.Draw(lDestinationPathSigned);   
       
        using (Process.Start(lDestinationPathSigned)) { }
       
    }
    
    X509Certificate2 GetSigningCertificate()
    {
        var lCertificateStore = new X509Store(StoreLocation.CurrentUser);
       
        try
        {
            lCertificateStore.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
           
            var lAllCertificates = (X509Certificate2Collection) lCertificateStore.Certificates;
            var lFilteredCertificates = (X509Certificate2Collection) lAllCertificates.Find(X509FindType.FindByTimeValid, DateTime.Now, true);
            lFilteredCertificates = (X509Certificate2Collection) lFilteredCertificates.Find(X509FindType.FindByKeyUsage, "DigitalSignature", true);
            var lSelectedCertificates = X509Certificate2UI.SelectFromCollection(
                lFilteredCertificates, "Select Certificate", "Please select a certificate to sign the PDF document.", X509SelectionFlag.SingleSelection);
           
            var lSelectedCertificate = lSelectedCertificates[0];
           
            return lSelectedCertificate;
        }
        finally
        {
            lCertificateStore.Close();
        }
    }

Is this an issue with DynamicPDF Merger, or is there another way to achieve my requirements using DynmaicPDF?
 Feb 05 2016 11:29 AM
Posted by a ceTe Software moderator
Hello,

We will do some testing to recreate the issue. We will post an update as soon as we are done with our testing.

Thanks,
ceTe Software Support Team.
 Feb 05 2016 12:27 PM
Thanks for the response - if you need any further assistance to reproduce the issue, please let me know and I'll help in any way I can.
 Feb 08 2016 4:44 PM
Posted by a ceTe Software moderator
Hello,

Any modifications to a signed document is supposed to invalidate the signature. When you fill a signed PDF form and save it, the signature will get invalidated by design. In this case you would need to revalidate the document by signing it again.

Currently our library is not capable of signing the signature fields that already exist on the PDF. If have control over the creation of original PDF, don’t include the signature field when you first generate it. When it is time to sign that PDF, just add a new signature field and sign it as shown below:

            //Open the PDF.
            PdfDocument pdf = new PdfDocument("PDFwithNoSignField.pdf");
            MergeDocument document = new MergeDocument(pdf);
            //Add a signature field, sign and save.
            var lSignatureField = new ceTe.DynamicPDF.PageElements.Forms.Signature("sigfield", 50, 200, 200, 200);
            document.Pages[0].Elements.Add(lSignatureField);
            document.Sign("sigfield", new Certificate("cert path", "cert password"));
            document.Draw("signed.pdf");

In case you do not have control over the incoming PDF and if it has a signature field, then you can remove that field and replace it with a new field and sign it as shown below:

            //Open the PDF.
            PdfDocument pdf = new PdfDocument("PDFwithSignField.pdf");
            MergeDocument document = new MergeDocument(pdf);

            //retrieve the properties of existing signature field.
            PdfFormField sigField = pdf.Form.Fields["sigfield"];
           
            float x = sigField.GetX(document.Pages[sigField.GetOriginalPageNumber()-1]);
            float y = sigField.GetY(document.Pages[sigField.GetOriginalPageNumber()-1]);

            float width = sigField.Width;
            float height = sigField.Height;

            //flag the old signature field to be removed.
            document.Form.Fields["sigfield"].Output = FormFieldOutput.Remove;

            //use the properties of old signature field to add a new signature field in its place, sign and save.
            var lSignatureField = new ceTe.DynamicPDF.PageElements.Forms.Signature("newsigfield", x, y, width, height);
            //var lSignatureField = new ceTe.DynamicPDF.PageElements.Forms.Signature("newsigfield", 50, 200, 200, 200);
            lSignatureField.Font = Font.Helvetica;
            document.Pages[0].Elements.Add(lSignatureField);
            document.Sign("sigfield", new Certificate("cert path", "cert password"));            
            document.Draw("signed.pdf");

Thanks,
ceTe Software Support Team.
 Feb 09 2016 8:30 AM
My use case is to add multiple signatures, each from a different user. This means one user signs the document and then, later, another user signs the document.

This process can be done using Adobe Reader, so it is possible from a overall PDF standpoint. If the form is modified and signed by another user, the PDF will indicate that the "Document has been modified since this signature was applied" but the signature itself will still exist in the document. If a second signature is applied and no form fields were modified then it states that "Document has not been modified since this signature was applied".

This document (pages 7 and 8) talk about this type of situation:

https://www.adobe.com/content/dam/Adobe/en/devnet/reader/pdfs/readercomp_digitalsignatures.pdf

Can you confirm that you're claiming DynamicPDF currently does not support signing a previously signed PDF?
 Feb 09 2016 8:34 AM
My previous response is being reviewed by a mod (probably because it contained a link to an Adobe document).

There may be confusion elsewhere and I want to clear it up. You say the original signature should be "invalidated" but I'm seeing it removed entirely. Is removing the signature what you mean by invalidating it?
 Feb 09 2016 4:41 PM
Posted by a ceTe Software moderator
Hello,

Yes, removing the signature is what we meant by invalidating. Sorry for the confusion.

Although possible from an overall PDF standpoint, DynamicPDF does not have the capability to sign a previously signed document. We have added this to the feature request list for consideration. However, at this point we don’t have any immediate plans to implement this feature.

Thanks,
ceTe Software Support Team.

All times are US Eastern Standard time. The time now is 4:35 PM.