pdf links

PDF Rendering
Convert PDF to Image (.NET)
Convert PDF to image on Android (Xamarin)
Convert PDF to image on iOS (Xamarin)
Convert PDF to image in Windows Store apps (.NET)
Convert PDF to image in Windows Phone apps (.NET)
PDF to image in Universal Windows Store apps (.NET)
Free PDF Viewer control for Windows Forms (.NET)
How to integrate PDF Viewer control in WPF app (.NET)
Creating WPF PDF Viewer supporting bookmarks (.NET)
Cross-platform PDF Viewer using GTK# (MONO)
Silverlight PDF viewer control (Silverlight 5)
Multithreaded PDF rendering (.NET)
Convert pdf to image in Silverlight app (C# sample)
How to set fallback fonts for PDF rendering (C#)
Avoiding the out-of-memory exception on rendering (C#)
PDF viewer single page application (WebAPI, AngularJS)
PDF viewer control for Windows 10 universal applications
Use custom ICC profile for CMYK to RGB conversion
PDF layers - separate images, text, annotations, graphics

PDF Forms Creation PDF Security
Conversion to PDF/A
Other topics
PDF Document Manipulation
PDF Content Generation
Fixed and Flow layout document API (.NET)
Creation of grids and tables in PDF (C# sample)
How to create interactive documents using Actions (C# sample)
Text flow effects in PDF (C# sample)
How to generate ordered and bulleted lists in PDF (C# sample)
Convert HTML to PDF using flow layout API (C# sample)
How to use custom fonts for PDF generation (.NET)
Create document with differently sized pages (C#)
Create PDF documents using MONO (C#/MONO/Windows/OSX)
How to use background images for content elements (C#/PDF Kit/FlowLayout)
Add transparent images to PDF document (C#)
Draw round rect borders in PDF documents(C#)
ICC color profiles and and ICC based colors in PDF (C#)
How to use bidirectional and right to left text in PDF (C#)
Create PDF documents from XML templates (C# sample)
How to resize PDF pages and use custom stamps (C#)
Add header and footer to PDF page (.NET sample)
How to use clipping mask for drawing on PDF page
Fill graphics path with gradient brushes in PDF (Shadings)
Apitron PDF Kit and Rasterizer engine settings
Add layers to PDF page (optional content, C# sample)
How to create free text annotation with custom appearance

PDF Content Extraction
PDF Navigation

PDF to TIFF conversion
Contact us if you have a PDF related question and we'll cover it in our blog.

2016-06-30

Setting custom properties for PDF signatures

Introduction


Software modules that digital signatures of the PDF file are called Filters (signature handlers) in PDF terms. There are a few existing filters e.g. Adobe.PPKLite or Adobe.PubSec.

When the signature object is being created it may have a preferred Filter property assigned to it. There is also an additional SubFilter property of the signature that defines how the signature data is being stored in the file; a few predefined values are as follows:

1. For signing PDF files using PKCS#1, the only value of SubFilter that should be used is adbe.x509.rsa_sha1, which uses the RSA encryption algorithm and SHA-1 digest method.

2. When PKCS#7 signatures are used allowed values are:

adbe.pkcs7.detached: The original signed message digest over the document’s byte range shall be incorporated as the normal PKCS#7 SignedData field. No data shall be encapsulated in the PKCS#7 SignedData field.

adbe.pkcs7.sha1: The SHA1 digest of the document’s byte range shall be encapsulated in the PKCS#7 SignedData field with ContentInfo of type Data. The digest of that SignedData shall be incorporated as the normal PKCS#7 digest.

Additional information can be found in PDF specification, see section 12.8.3 Signature Interoperability. It is intended that conforming readers allow interoperability between signature handlers; that is, a PDF file signed with a handler from one provider shall be able to be validated with a handler from a different provider.

If present, the SubFilter property of the signature shall specify the encoding of the signature value and key information, while the Filter property shall specify the preferred handler that should be used to validate the signature. When handlers are being registered according to specification they shall specify the SubFilter encodings they support enabling handlers other than the originally used to validate the signatures created.

So, to summarize all the things above: Filter - defines validation module, SubFilter – defines how to store the signature value and key info in PDF file.

In this example we’ll set a few custom properties for the signature, namely the name of the application that created the signature and GPS coordinates of the signer’s location.

Internally it uses the SignatureField.PropBuild dictionary to set the software module name when the signature is being created. PropBuild dictionary is a special dictionary that allows writing custom values along with the signature. Read the PDF Signature Build Dictionary Specification to find details about it.

The code


class Program
{
    private static void Sign(string pathToDocument, string pathToCertificate, 
        string password, string pathToSignatureImage, Boundary signatureViewLocation)
    {           
        // open existing document andd sign once
        using (Stream inputStream = new FileStream( pathToDocument,
            FileMode.Open, FileAccess.ReadWrite))
        {
            using (FixedDocument doc = new FixedDocument(inputStream))
            {
                string imageResourceId = Guid.NewGuid().ToString("N");
                string signatureFieldId = Guid.NewGuid().ToString("N");

                // register signature image resource
                doc.ResourceManager.RegisterResource(new Image(imageResourceId,
                    pathToSignatureImage));

                // create first signature field and initialize it using a stored certificate
                SignatureField signatureField = new SignatureField(signatureFieldId);
                using (Stream signatureDataStream = File.OpenRead(pathToCertificate))
                {
                    signatureField.Signature = new Pkcs7DetachedSignature(
                        new Pkcs12Store(signatureDataStream,password));
                    // set the software module name
                    signatureField.Signature.SoftwareModuleName =
                       "MyApp based on Apitron PDF Kit for .NET";        
                    // set the GEO location of the place where the signature was created
                    signatureField.PropBuild.SetValue("GEOTAG", "38.8977° N, 77.0365° W");
                }

                // add signature fields to the document
                doc.AcroForm.Fields.Add(signatureField);

                // create first signature view using the image resource
                SignatureFieldView signatureView = new SignatureFieldView(signatureField,
                    signatureViewLocation);
                signatureView.ViewSettings.Graphic = Graphic.Image;
                signatureView.ViewSettings.GraphicResourceID = imageResourceId;
                signatureView.ViewSettings.Description = Description.None;

                // add views to page annotations collection
                doc.Pages[0].Annotations.Add(signatureView);

                // save as incremental update
                doc.Save();
            }
        }

        Process.Start("signed.pdf");
    }
   
    private static void CreatePDFDocument(string fileName)
    {
        using (Stream stream = File.Create(fileName))
        {
            FlowDocument doc = new FlowDocument() { Margin = new Thickness(10) };
            doc.Add(new TextBlock("Signed using Apitron PDF Kit for .NET, 
                the signature has a custom
                property containing app name. " +
               "Click on the signature image and select \"Signature Properties...\"-
               >\"Advanced Properties...\""));
            doc.Write(stream, new ResourceManager());
        }
    }

    static void Main(string[] args)
    {
        string fileName = "signed.pdf";

        CreatePDFDocument(fileName);

        // sign once and save
        Sign(fileName, "../../data/certs/JohnDoe.pfx", "password",  
            "../../data/images/signatureImage.png"
            new Boundary(10, 750, 110, 800));                               
    }      
}

Please note that setting custom properties using PropBuild dictionary is only possible if you use PKCS7 detached signature. The complete code sample can be found in our github repo.

And the result:

Pic. 1 Custom signature properties added using Apitron PDF Kit for .NET

Pic. 1 Custom signature properties added using Apitron PDF Kit for .NET

Summary


As you can see, Apitron PDF Kit provides an easy to use API that allows you to solve complex tasks like signing PDF and setting custom signature properties using a couple lines of code. Additionally, its cross-platform nature simplifies development if you’re targeting multiple platforms at once e.g. .NET ecosystem, Android and iOS (using Xamarin) as it’s available for all modern web, desktop or mobile platforms. Contact us if you have any questions and we’ll be happy to help you. 

No comments:

Post a Comment