VintaSoft Imaging .NET SDK 14.0: Документация для .NET разработчика
В этом разделе
    PDF: Использование цифровых подписей в PDF документах
    В этом разделе
    Цифровая подпись используется для подтверждения подлинности личности пользователя и достоверности содержимого документа.
    SDK позволяет:

    Добавление цифровой подписи в PDF документ

    Чтобы подписать PDF документ с помощью цифровой подписи, необходимо сделать следующее:
    Вот C#/VB.NET код, который демонстрирует, как подписать PDF документ с помощью цифровой подписи:
    /// <summary>
    /// Signs a PDF or PDF/A document using specified certificate.
    /// </summary>
    /// <param name="inputFilename">The filename of input PDF document.</param>
    /// <param name="outputFilename">The filename of output PDF document.</param>
    /// <param name="certificate">The certificate that should be used
    /// for signing the input PDF document.</param>
    /// <param name="conformance">The conformance of PDF document.</param>
    public static void SignDocument(
        string inputFilename,
        string outputFilename,
        Vintasoft.Imaging.Pdf.PdfDocumentConformance conformance,
        System.Security.Cryptography.X509Certificates.X509Certificate2 certificate)
    {
        SignDocument(inputFilename, outputFilename, conformance, certificate, false, null);
    }
    
    /// <summary>
    /// Signs with timestamp a PDF or PDF/A document using specified certificate.
    /// </summary>
    /// <param name="inputFilename">The filename of input PDF document.</param>
    /// <param name="outputFilename">The filename of output PDF document.</param>
    /// <param name="certificate">The certificate that should be used
    /// for signing the input PDF document.</param>
    /// <param name="addCertificateChain">A value indicating whether signing certificate chain must be added to signature.</param>
    /// <param name="conformance">The conformance of PDF document.</param>
    /// <param name="timestampServerUrl">Timestamp server URL.</param>
    public static void SignDocument(
        string inputFilename,
        string outputFilename,
        Vintasoft.Imaging.Pdf.PdfDocumentConformance conformance,
        System.Security.Cryptography.X509Certificates.X509Certificate2 certificate,
        bool addCertificateChain,
        string timestampServerUrl)
    {
        Vintasoft.Imaging.Pdf.Processing.PdfDocumentConverter converter = null;
    
        // if PDF document conformance is specified
        if (conformance != Vintasoft.Imaging.Pdf.PdfDocumentConformance.Undefined)
        {
            // create PDF document converter
            converter = Vintasoft.Imaging.Pdf.Processing.PdfDocumentConverter.Create(conformance);
    
            // if is PDF/A converter
            Vintasoft.Imaging.Pdf.Processing.PdfA.PdfAConverter pdfAConverter = converter as Vintasoft.Imaging.Pdf.Processing.PdfA.PdfAConverter;
            if (pdfAConverter != null)
            {
                // set ICC profiles
                //pdfAConverter.DefaultCmykIccProfileFilename = "DefaultCMYK.icc";
                //pdfAConverter.DefaultRgbIccProfileFilename = "DefaultRGB.icc";
            }
    
            // if PDF document converter is not found
            if (converter == null)
            {
                string message = string.Format("Unsupported {0} conformance.", conformance);
                throw new System.ArgumentOutOfRangeException(message);
            }
        }
    
        // open PDF document
        using (Vintasoft.Imaging.Pdf.PdfDocument document = new Vintasoft.Imaging.Pdf.PdfDocument(inputFilename))
        {
            // add signature
            AddSignature(document, certificate, addCertificateChain, timestampServerUrl, 1);
    
            // if PDF document cannot be converted
            if (converter == null)
            {
                if (inputFilename == outputFilename)
                {
                    // sign PDF document and save changes in PDF document
                    document.SaveChanges();
                }
                else
                {
                    // sign PDF document and save PDF document to the output file
                    document.SaveChanges(outputFilename);
                }
            }
            else
            {
                if (inputFilename != outputFilename)
                {
                    Vintasoft.Imaging.Pdf.Processing.PdfA.PdfAConverter pdfAConverter =
                        (Vintasoft.Imaging.Pdf.Processing.PdfA.PdfAConverter)converter;
                    pdfAConverter.OutputFilename = outputFilename;
                }
    
                // sign and convert PDF document
                Vintasoft.Imaging.Processing.ConversionProfileResult conversionResult =
                    converter.Convert(document, new Vintasoft.Imaging.Processing.ProcessingState());
    
                // if conversion falied
                if (!conversionResult.IsSuccessful)
                {
                    // throw conversion exception
                    throw conversionResult.CreateConversionException();
                }
            }
        }
    }
    
    /// <summary>
    /// Adds a digital signature to specified PDF document.
    /// </summary>
    /// <param name="document">The PDF document.</param>
    /// <param name="certificate">The certificate that should be added.</param>
    /// <param name="timestampServerUrl">Timestamp server URL.</param>
    /// <param name="addCertificateChain">A value indicating whether signing certificate chain must be added to signature.</param>
    /// <param name="sigNumber">The number of signature field.</param>
    private static void AddSignature(
        Vintasoft.Imaging.Pdf.PdfDocument document,
        System.Security.Cryptography.X509Certificates.X509Certificate2 certificate,
        bool addCertificateChain,
        string timestampServerUrl,
        int sigNumber)
    {
        // if PDF document does not have interactive form
        if (document.InteractiveForm == null)
        {
            // create the interactive form in document
            document.InteractiveForm = new Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfDocumentInteractiveForm(document);
        }
    
        // specify that document contains signatures
        document.InteractiveForm.SignatureFlags =
            Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfDocumentSignatureFlags.SignaturesExist |
            Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfDocumentSignatureFlags.AppendOnly;
    
        // specify that the viewer application must NOT construct appearance streams and
        // appearance properties for widget annotations in the document
        document.InteractiveForm.NeedAppearances = false;
    
        // get PDF page on which signature will be placed
        Vintasoft.Imaging.Pdf.Tree.PdfPage page = document.Pages[0];
    
        // calculate the signature field rectangle (field will be placed in the bottom-center of page)
        System.Drawing.RectangleF signatureRect = new System.Drawing.RectangleF();
        signatureRect.Width = page.MediaBox.Width / 5;
        signatureRect.Height = signatureRect.Width / 3;
        signatureRect.X = page.MediaBox.X + (page.MediaBox.Width - signatureRect.Width) / 2;
        signatureRect.Y = page.MediaBox.Y + signatureRect.Height * sigNumber;
    
        // create parameters for creation of PKCS#7 signature
        Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignatureCreationParams creationParams =
            new Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignatureCreationParams(certificate, addCertificateChain);
        // if timestamp server is specified
        if (!string.IsNullOrEmpty(timestampServerUrl))
        {
            // specify the timestamp authority client
            creationParams.TimestampAuthorityClient = new Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.TimestampAuthorityWebClient(timestampServerUrl);
        }
    
        // create PKCS#7 signature
        Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignature signature = Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignature.CreatePkcs7Signature(
             document.Format, creationParams);
    
        // create signature info
        Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfSignatureInformation signatureInfo =
            new Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfSignatureInformation(document, signature);
        signatureInfo.SignerName = certificate.GetNameInfo(
            System.Security.Cryptography.X509Certificates.X509NameType.SimpleName, false);
        signatureInfo.Reason = "Test signing";
        signatureInfo.Location = System.Globalization.CultureInfo.CurrentCulture.EnglishName;
        signatureInfo.SigningTime = System.DateTime.Now;
    
        // create the signature field
        Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfInteractiveFormSignatureField signatureField =
            new Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfInteractiveFormSignatureField(document, string.Format("MySignature{0}", sigNumber), signatureRect);
    
        // set the signature information
        signatureField.SignatureInfo = signatureInfo;
    
        // create the signature appearance
        using (Vintasoft.Imaging.Pdf.Drawing.PdfGraphics g = signatureField.CreateAppearanceGraphics())
        {
            // signature text
            string signatureText = string.Format("Digitally signed by\n{0}",
                signatureInfo.SignerName);
    
            // signature appearance rect
            System.Drawing.RectangleF rect = new System.Drawing.RectangleF(
                System.Drawing.PointF.Empty,
                signatureField.Annotation.Rectangle.Size);
    
            // draw background
            g.FillRectangle(new Vintasoft.Imaging.Pdf.Drawing.PdfBrush(
                System.Drawing.Color.FromArgb(255, System.Drawing.Color.Lime)), rect);
    
            // padding
            rect.Inflate(-rect.Height / 10, -rect.Height / 10);
    
            // create TimesRoman font
            Vintasoft.Imaging.Pdf.Tree.Fonts.PdfFont font = document.FontManager.GetStandardFont(
                Vintasoft.Imaging.Pdf.Tree.Fonts.PdfStandardFontType.TimesRoman);
    
            // measure font size
            float fontSize = g.MeasureFontSize(signatureText, font, rect.Width, rect.Height);
    
            // draw signture text
            g.DrawString(
                signatureText,
                font, fontSize, new Vintasoft.Imaging.Pdf.Drawing.PdfBrush(System.Drawing.Color.Black),
                rect, Vintasoft.Imaging.Pdf.Drawing.PdfContentAlignment.Center, false);
        }
    
        // add signature field to the interactive form of document
        document.InteractiveForm.Fields.Add(signatureField);
    
        // if PDF page does not have annotations
        if (page.Annotations == null)
            // create an empty annotation collection for page
            page.Annotations = new Vintasoft.Imaging.Pdf.Tree.Annotations.PdfAnnotationList(document);
        // add widget annotation of signature field to the annotation collection of page
        page.Annotations.Add(signatureField.Annotation);
    }
    
    ''' <summary>
    ''' Signs a PDF or PDF/A document using specified certificate.
    ''' </summary>
    ''' <param name="inputFilename">The filename of input PDF document.</param>
    ''' <param name="outputFilename">The filename of output PDF document.</param>
    ''' <param name="certificate">The certificate that should be used
    ''' for signing the input PDF document.</param>
    ''' <param name="conformance">The conformance of PDF document.</param>
    Public Shared Sub SignDocument(inputFilename As String, outputFilename As String, conformance As Vintasoft.Imaging.Pdf.PdfDocumentConformance, certificate As System.Security.Cryptography.X509Certificates.X509Certificate2)
        SignDocument(inputFilename, outputFilename, conformance, certificate, False, Nothing)
    End Sub
    
    ''' <summary>
    ''' Signs with timestamp a PDF or PDF/A document using specified certificate.
    ''' </summary>
    ''' <param name="inputFilename">The filename of input PDF document.</param>
    ''' <param name="outputFilename">The filename of output PDF document.</param>
    ''' <param name="certificate">The certificate that should be used
    ''' for signing the input PDF document.</param>
    ''' <param name="addCertificateChain">A value indicating whether signing certificate chain must be added to signature.</param>
    ''' <param name="conformance">The conformance of PDF document.</param>
    ''' <param name="timestampServerUrl">Timestamp server URL.</param>
    Public Shared Sub SignDocument(inputFilename As String, outputFilename As String, conformance As Vintasoft.Imaging.Pdf.PdfDocumentConformance, certificate As System.Security.Cryptography.X509Certificates.X509Certificate2, addCertificateChain As Boolean, timestampServerUrl As String)
        Dim converter As Vintasoft.Imaging.Pdf.Processing.PdfDocumentConverter = Nothing
    
        ' if PDF document conformance is specified
        If conformance <> Vintasoft.Imaging.Pdf.PdfDocumentConformance.Undefined Then
            ' create PDF document converter
            converter = Vintasoft.Imaging.Pdf.Processing.PdfDocumentConverter.Create(conformance)
    
            ' if is PDF/A converter
            Dim pdfAConverter As Vintasoft.Imaging.Pdf.Processing.PdfA.PdfAConverter = TryCast(converter, Vintasoft.Imaging.Pdf.Processing.PdfA.PdfAConverter)
                    ' set ICC profiles
                    'pdfAConverter.DefaultCmykIccProfileFilename = "DefaultCMYK.icc";
                    'pdfAConverter.DefaultRgbIccProfileFilename = "DefaultRGB.icc";
            If pdfAConverter IsNot Nothing Then
            End If
    
            ' if PDF document converter is not found
            If converter Is Nothing Then
                Dim message As String = String.Format("Unsupported {0} conformance.", conformance)
                Throw New System.ArgumentOutOfRangeException(message)
            End If
        End If
    
        ' open PDF document
        Using document As New Vintasoft.Imaging.Pdf.PdfDocument(inputFilename)
            ' add signature
            AddSignature(document, certificate, addCertificateChain, timestampServerUrl, 1)
    
            ' if PDF document cannot be converted
            If converter Is Nothing Then
                If inputFilename = outputFilename Then
                    ' sign PDF document and save changes in PDF document
                    document.SaveChanges()
                Else
                    ' sign PDF document and save PDF document to the output file
                    document.SaveChanges(outputFilename)
                End If
            Else
                If inputFilename <> outputFilename Then
                    Dim pdfAConverter As Vintasoft.Imaging.Pdf.Processing.PdfA.PdfAConverter = DirectCast(converter, Vintasoft.Imaging.Pdf.Processing.PdfA.PdfAConverter)
                    pdfAConverter.OutputFilename = outputFilename
                End If
    
                ' sign and convert PDF document
                Dim conversionResult As Vintasoft.Imaging.Processing.ConversionProfileResult = converter.Convert(document, New Vintasoft.Imaging.Processing.ProcessingState())
    
                ' if conversion falied
                If Not conversionResult.IsSuccessful Then
                    ' throw conversion exception
                    Throw conversionResult.CreateConversionException()
                End If
            End If
        End Using
    End Sub
    
    ''' <summary>
    ''' Adds a digital signature to specified PDF document.
    ''' </summary>
    ''' <param name="document">The PDF document.</param>
    ''' <param name="certificate">The certificate that should be added.</param>
    ''' <param name="timestampServerUrl">Timestamp server URL.</param>
    ''' <param name="addCertificateChain">A value indicating whether signing certificate chain must be added to signature.</param>
    ''' <param name="sigNumber">The number of signature field.</param>
    Private Shared Sub AddSignature(document As Vintasoft.Imaging.Pdf.PdfDocument, certificate As System.Security.Cryptography.X509Certificates.X509Certificate2, addCertificateChain As Boolean, timestampServerUrl As String, sigNumber As Integer)
        ' if PDF document does not have interactive form
        If document.InteractiveForm Is Nothing Then
            ' create the interactive form in document
            document.InteractiveForm = New Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfDocumentInteractiveForm(document)
        End If
    
        ' specify that document contains signatures
        document.InteractiveForm.SignatureFlags = Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfDocumentSignatureFlags.SignaturesExist Or Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfDocumentSignatureFlags.AppendOnly
    
        ' specify that the viewer application must NOT construct appearance streams and
        ' appearance properties for widget annotations in the document
        document.InteractiveForm.NeedAppearances = False
    
        ' get PDF page on which signature will be placed
        Dim page As Vintasoft.Imaging.Pdf.Tree.PdfPage = document.Pages(0)
    
        ' calculate the signature field rectangle (field will be placed in the bottom-center of page)
        Dim signatureRect As New System.Drawing.RectangleF()
        signatureRect.Width = page.MediaBox.Width / 5
        signatureRect.Height = signatureRect.Width / 3
        signatureRect.X = page.MediaBox.X + (page.MediaBox.Width - signatureRect.Width) / 2
        signatureRect.Y = page.MediaBox.Y + signatureRect.Height * sigNumber
    
        ' create parameters for creation of PKCS#7 signature
        Dim creationParams As New Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignatureCreationParams(certificate, addCertificateChain)
        ' if timestamp server is specified
        If Not String.IsNullOrEmpty(timestampServerUrl) Then
            ' specify the timestamp authority client
            creationParams.TimestampAuthorityClient = New Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.TimestampAuthorityWebClient(timestampServerUrl)
        End If
    
        ' create PKCS#7 signature
        Dim signature As Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignature = Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignature.CreatePkcs7Signature(document.Format, creationParams)
    
        ' create signature info
        Dim signatureInfo As New Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfSignatureInformation(document, signature)
        signatureInfo.SignerName = certificate.GetNameInfo(System.Security.Cryptography.X509Certificates.X509NameType.SimpleName, False)
        signatureInfo.Reason = "Test signing"
        signatureInfo.Location = System.Globalization.CultureInfo.CurrentCulture.EnglishName
        signatureInfo.SigningTime = System.DateTime.Now
    
        ' create the signature field
        Dim signatureField As New Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfInteractiveFormSignatureField(document, String.Format("MySignature{0}", sigNumber), signatureRect)
    
        ' set the signature information
        signatureField.SignatureInfo = signatureInfo
    
        ' create the signature appearance
        Using g As Vintasoft.Imaging.Pdf.Drawing.PdfGraphics = signatureField.CreateAppearanceGraphics()
            ' signature text
            Dim signatureText As String = String.Format("Digitally signed by" & vbLf & "{0}", signatureInfo.SignerName)
    
            ' signature appearance rect
            Dim rect As New System.Drawing.RectangleF(System.Drawing.PointF.Empty, signatureField.Annotation.Rectangle.Size)
    
            ' draw background
            g.FillRectangle(New Vintasoft.Imaging.Pdf.Drawing.PdfBrush(System.Drawing.Color.FromArgb(255, System.Drawing.Color.Lime)), rect)
    
            ' padding
            rect.Inflate(-rect.Height / 10, -rect.Height / 10)
    
            ' create TimesRoman font
            Dim font As Vintasoft.Imaging.Pdf.Tree.Fonts.PdfFont = document.FontManager.GetStandardFont(Vintasoft.Imaging.Pdf.Tree.Fonts.PdfStandardFontType.TimesRoman)
    
            ' measure font size
            Dim fontSize As Single = g.MeasureFontSize(signatureText, font, rect.Width, rect.Height)
    
            ' draw signture text
            g.DrawString(signatureText, font, fontSize, New Vintasoft.Imaging.Pdf.Drawing.PdfBrush(System.Drawing.Color.Black), rect, Vintasoft.Imaging.Pdf.Drawing.PdfContentAlignment.Center, _
                False)
        End Using
    
        ' add signature field to the interactive form of document
        document.InteractiveForm.Fields.Add(signatureField)
    
        ' if PDF page does not have annotations
        If page.Annotations Is Nothing Then
            ' create an empty annotation collection for page
            page.Annotations = New Vintasoft.Imaging.Pdf.Tree.Annotations.PdfAnnotationList(document)
        End If
        ' add widget annotation of signature field to the annotation collection of page
        page.Annotations.Add(signatureField.Annotation)
    End Sub
    


    Проверка цифровой подписи

    Для проверки цифровой подписи PDF документа необходимо сделать следующее:
    Вот C#/VB.NET код, который демонстрирует, как проверить, является ли подпись PDF документа подлинной:
    /// <summary>
    /// Displays and verifies signatures of PDF document.
    /// </summary>
    /// <param name="pdfFilename">The filename of PDF document.</param>
    public static void VerifyDocumentSignatures(string pdfFilename)
    {
        // open PDF document
        using (Vintasoft.Imaging.Pdf.PdfDocument document = 
            new Vintasoft.Imaging.Pdf.PdfDocument(pdfFilename))
        {
            // if document does not have interactive form
            if (document.InteractiveForm == null)
            {
                System.Console.WriteLine("Signature fields are not found.");
                return;
            }
    
            // get an array of signature fields of document
            Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfInteractiveFormSignatureField[] signatureFields =
                document.InteractiveForm.GetSignatureFields();
            // if document does not have signature fields
            if (signatureFields.Length == 0)
            {
                System.Console.WriteLine("Signture fields are not found.");
                return;
            }
    
            // for each signature field
            for (int i = 0; i < signatureFields.Length; i++)
            {
                // get reference to the signature field
                Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfInteractiveFormSignatureField signatureField = signatureFields[i];
                // print signature field name
                System.Console.WriteLine(string.Format("[{0}]Signaure field: {1}", i + 1, signatureField.FullyQualifiedName));
    
                // get information about signature
                Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfSignatureInformation signatureInfo = signatureField.SignatureInfo;
                // if signature information is empty
                if (signatureInfo == null)
                {
                    System.Console.WriteLine("Empty signature field.");
                }
                // if signature information is NOT empty
                else
                {
                    // check is document timestamp signature
                    if (signatureInfo.IsTimeStamp)
                        System.Console.WriteLine("Signature is a document timestamp signature");
    
                    // print signature filter
                    System.Console.WriteLine(string.Format("Filter      : {0} ({1})", signatureInfo.Filter, signatureInfo.SubFilter));
                    // print the signer name
                    if (signatureInfo.SignerName != null)
                        System.Console.WriteLine(string.Format("Signed by   : {0}", signatureInfo.SignerName));
                    // print the signature reason
                    if (signatureInfo.Reason != null)
                        System.Console.WriteLine(string.Format("Reason      : {0}", signatureInfo.Reason));
                    // print the signature location
                    if (signatureInfo.Location != null)
                        System.Console.WriteLine(string.Format("Location    : {0}", signatureInfo.Location));
                    // print the signer contact info
                    if (signatureInfo.ContactInfo != null)
                        System.Console.WriteLine(string.Format("Contact Info: {0}", signatureInfo.SignerName));
                    // print the signing date
                    if (signatureInfo.SigningTime != System.DateTime.MinValue)
                        System.Console.WriteLine(string.Format("Signig Date : {0}", signatureInfo.SigningTime.ToString("f")));
    
                    // get PKCS signature
                    bool error = false;
                    Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignature signature = null;
                    try
                    {
                        signature = signatureInfo.GetSignature();
                    }
                    catch (System.Exception e)
                    {
                        error = true;
                        System.Console.WriteLine("PKCS signature parsing error: {0}", e.Message);
                    }
                    if (error)
                        continue;
    
                    // print name of signature algorithm
                    System.Console.WriteLine(string.Format("Algorithm   : {0}", signature.SignatureAlgorithmName));
    
                    // print information about signature certificate chain
                    System.Console.WriteLine("Sign certificate chain:");
                    System.Security.Cryptography.X509Certificates.X509Certificate2[] signCertChain = 
                        signature.SigningCertificateChain;
                    string padding = "";
                    foreach (System.Security.Cryptography.X509Certificates.X509Certificate2 cert in signCertChain)
                    {
                        padding += "    ";
                        System.Console.WriteLine("{0}Serial number: {1}", padding, cert.SerialNumber);
                        System.Console.WriteLine("{0}Issuer       : {1}", padding, cert.GetNameInfo(
                            System.Security.Cryptography.X509Certificates.X509NameType.SimpleName, true));
                        System.Console.WriteLine("{0}Subject      : {1}", padding, cert.GetNameInfo(
                            System.Security.Cryptography.X509Certificates.X509NameType.SimpleName, false));
                    }
    
    
                    // verify digital signature
                    VerifyDigitalSignature(signatureInfo, signature);
                }
                System.Console.WriteLine();
            }
        }
    }
    
    /// <summary>
    /// Verifies the digital signature.
    /// </summary>
    /// <param name="signature">The signature.</param>
    /// <param name="signatureInfo">The signature information.</param>
    /// <returns><b>true</b> if signature is valid; otherwise, <b>false</b>.</returns>
    public static bool VerifyDigitalSignature(
        Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfSignatureInformation signatureInfo,
        Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignature signature)
    {
        System.Console.WriteLine("Verifying signature...");
    
        bool signatureVerifyResult = false;
        bool embeddedTimestampVerifyResult = false;
        bool certificateVerifyResult = false;
        bool embeddedTimestampCertificateVerifyResult = false;
        bool signatureCoversWholeDocument = false;
        System.Security.Cryptography.X509Certificates.X509Chain certificateChain = null;
        System.Security.Cryptography.X509Certificates.X509Chain timestampCertificateChain = null;
    
    
        // verify signature
    
        try
        {
            // check that signature covers the whole document
            signatureCoversWholeDocument = signatureInfo.SignatureCoversWholeDocument();
    
            // verify PKCS signature
            signatureVerifyResult = signature.VerifySignature();
    
            // if signature has embedded timestamp
            if (signature.HasEmbeddedTimeStamp)
            {
                // verify embedded timestamp
                embeddedTimestampVerifyResult = signature.VerifyTimestamp();
            }
    
            // build and verify certificate chain
            certificateChain = new System.Security.Cryptography.X509Certificates.X509Chain();
            certificateVerifyResult = certificateChain.Build(signature.SigningCertificate);
    
            // if signature has embedded timestamp
            if (signature.HasEmbeddedTimeStamp)
            {
                // build and verify timestamp certificate chain
                timestampCertificateChain = new System.Security.Cryptography.X509Certificates.X509Chain();
                embeddedTimestampCertificateVerifyResult = certificateChain.Build(signature.TimestampCertificate);
            }
    
        }
        catch (System.Exception verificationException)
        {
            System.Console.WriteLine("Verification failed: {0}", verificationException.Message);
            return false;
        }
    
        bool pageContentModified = false;
        string subsequentChangesMessage = "";
        // if PKCS signature verification is passed AND signature does not cover the whole document
        if (signatureVerifyResult && !signatureCoversWholeDocument)
        {
            try
            {
                // if signature has revision info
                if (signatureInfo.SignedRevision != null)
                {
                    // check subsequent changes
                    using (Vintasoft.Imaging.Pdf.PdfDocumentRevisionComparer documentChanges = signatureInfo.GetDocumentChanges())
                    {
                        // check subsequent changes in pages content
                        pageContentModified = documentChanges.HasModifiedPages;
    
                        // build subsequent changes message
                        if (documentChanges.ChangedPageContents.Count > 0)
                            subsequentChangesMessage += string.Format("{0} page(s) modified; ", documentChanges.ChangedPageContents.Count);
                        if (documentChanges.AddedPages.Count > 0)
                            subsequentChangesMessage += string.Format("{0} page(s) added; ", documentChanges.AddedPages.Count);
                        if (documentChanges.RemovedPages.Count > 0)
                            subsequentChangesMessage += string.Format("{0} page(s) removed; ", documentChanges.RemovedPages.Count);
                        if (documentChanges.RemovedAnnotations.Count > 0)
                            subsequentChangesMessage += string.Format("annotations(s) on {0} page(s) removed; ", documentChanges.RemovedAnnotations.Count);
                        if (documentChanges.RemovedAnnotations.Count > 0)
                            subsequentChangesMessage += string.Format("removed annotation(s) on {0} page(s); ", documentChanges.RemovedAnnotations.Count);
                        if (documentChanges.AddedAnnotations.Count > 0)
                            subsequentChangesMessage += string.Format("added annotation(s) on {0} page(s); ", documentChanges.AddedAnnotations.Count);
                        if (documentChanges.ChangedAnnotations.Count > 0)
                            subsequentChangesMessage += string.Format("changed annotation(s) on {0} page(s); ", documentChanges.ChangedAnnotations.Count);
                        if (documentChanges.MiscellaneousChanges.Count > 0)
                            subsequentChangesMessage += string.Format("miscellaneous changes: {0}; ", documentChanges.MiscellaneousChanges.Count);
                    }
                }
            }
            catch (System.Exception verificationException)
            {
                System.Console.WriteLine("Verification failed: {0}", verificationException.Message);
                return false;
            }
        }
    
        // print signature verification result
    
        // if PKCS signature verification is failed OR
        // signature does not cover the whole document AND page(s) content is modified
        if (!signatureVerifyResult || (!signatureCoversWholeDocument && pageContentModified))
            System.Console.WriteLine("Signature is INVALID.");
        // if certificate verification is failed
        else if (!certificateVerifyResult || (signature.HasEmbeddedTimeStamp && (!embeddedTimestampCertificateVerifyResult || !embeddedTimestampVerifyResult)))
            System.Console.WriteLine("Signature validity is UNKNOWN.");
        else
            System.Console.WriteLine("Signature is VALID.");
    
    
        // print signature verification details
    
        // if signature verification is successful
        if (signatureVerifyResult)
        {
            // if signature covers the whole document
            if (signatureCoversWholeDocument)
            {
                System.Console.WriteLine("    Signature verification: Document has not been modified since this signature was applied.");
            }
            // if signature does NOT cover the whole document
            else
            {
                if (pageContentModified)
                {
                    System.Console.WriteLine("    Signature verification: Document has been modified or corrupted since it was signed.");
                    System.Console.WriteLine(string.Format("    Subsequent changes: {0}.", subsequentChangesMessage));
                }
                else if (subsequentChangesMessage != "")
                {
                    System.Console.WriteLine("    Signature verification: The revision of the document that was covered by this signature has not been altered; however, there have been subsequent changes to the document.");
                    System.Console.WriteLine(string.Format("    Subsequent changes: {0}.", subsequentChangesMessage));
                }
                else
                {
                    System.Console.WriteLine("    Signature verification: Document has not been modified since this signature was applied.");
                }
            }
        }
        // if signature verification is NOT successful
        else
        {
            System.Console.WriteLine("    Signature verification: Document has been modified or corrupted since it was signed.");
        }
    
        // if signature has embedded timestamp
        if (signature.HasEmbeddedTimeStamp)
        {
            if (embeddedTimestampVerifyResult)
                System.Console.WriteLine("    Timestamp verification: Timestamp is valid.");
            else
                System.Console.WriteLine("    Timestamp verification: Timestamp is valid.");
        }
    
    
        // print certificate verification details
    
        // if certificate chain is present
        if (certificateChain != null)
        {
            // if certificate verification is successful
            if (certificateVerifyResult)
            {
                System.Console.WriteLine("    Certificate verification: Signer's certificate is valid.");
            }
            // if certificate verification is NOT successful
            else
            {
                // print certificate verification status
                System.Console.WriteLine("    Certificate verification: Signer's certificate is invalid:");
                foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in certificateChain.ChainStatus)
                    System.Console.Write(string.Format("        {0}: {1}", status.Status, status.StatusInformation));
            }
        }
    
        // if timestamp certificate chain is present
        if (timestampCertificateChain != null)
        {
            // if timestamp certificate verification is successful
            if (embeddedTimestampCertificateVerifyResult)
            {
                System.Console.WriteLine("    Timestamp certificate verification: Signer's certificate is valid.");
            }
            // if timestamp certificate verification is NOT successful
            else
            {
                // print certificate verification status
                System.Console.WriteLine("    Timestamp certificate verification: Signer's certificate is invalid:");
                foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in timestampCertificateChain.ChainStatus)
                    System.Console.Write(string.Format("        {0}: {1}", status.Status, status.StatusInformation));
            }
        }
    
        // if signature is not verified
        if (!signatureVerifyResult)
            return false;
    
        // if signature does NOT cover the whole document and page content was modified
        if (!signatureCoversWholeDocument && pageContentModified)
            return false;
    
        // if signature certificate is NOT verified
        if (!certificateVerifyResult)
            return false;
        
        if (signature.HasEmbeddedTimeStamp)
        {
            // if timestamp is NOT verified
            if (!embeddedTimestampVerifyResult)
                return false;
    
            // if timestamp certifiacet is NOT verified
            if (!embeddedTimestampCertificateVerifyResult)
                return false;
        }
    
        // sigature is VALID
        return true;
    }
    
    ''' <summary>
    ''' Displays and verifies signatures of PDF document.
    ''' </summary>
    ''' <param name="pdfFilename">The filename of PDF document.</param>
    Public Shared Sub VerifyDocumentSignatures(pdfFilename As String)
        ' open PDF document
        Using document As New Vintasoft.Imaging.Pdf.PdfDocument(pdfFilename)
            ' if document does not have interactive form
            If document.InteractiveForm Is Nothing Then
                System.Console.WriteLine("Signature fields are not found.")
                Return
            End If
    
            ' get an array of signature fields of document
            Dim signatureFields As Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfInteractiveFormSignatureField() = document.InteractiveForm.GetSignatureFields()
            ' if document does not have signature fields
            If signatureFields.Length = 0 Then
                System.Console.WriteLine("Signture fields are not found.")
                Return
            End If
    
            ' for each signature field
            For i As Integer = 0 To signatureFields.Length - 1
                ' get reference to the signature field
                Dim signatureField As Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfInteractiveFormSignatureField = signatureFields(i)
                ' print signature field name
                System.Console.WriteLine(String.Format("[{0}]Signaure field: {1}", i + 1, signatureField.FullyQualifiedName))
    
                ' get information about signature
                Dim signatureInfo As Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfSignatureInformation = signatureField.SignatureInfo
                ' if signature information is empty
                If signatureInfo Is Nothing Then
                    System.Console.WriteLine("Empty signature field.")
                Else
                    ' if signature information is NOT empty
                    ' check is document timestamp signature
                    If signatureInfo.IsTimeStamp Then
                        System.Console.WriteLine("Signature is a document timestamp signature")
                    End If
    
                    ' print signature filter
                    System.Console.WriteLine(String.Format("Filter      : {0} ({1})", signatureInfo.Filter, signatureInfo.SubFilter))
                    ' print the signer name
                    If signatureInfo.SignerName IsNot Nothing Then
                        System.Console.WriteLine(String.Format("Signed by   : {0}", signatureInfo.SignerName))
                    End If
                    ' print the signature reason
                    If signatureInfo.Reason IsNot Nothing Then
                        System.Console.WriteLine(String.Format("Reason      : {0}", signatureInfo.Reason))
                    End If
                    ' print the signature location
                    If signatureInfo.Location IsNot Nothing Then
                        System.Console.WriteLine(String.Format("Location    : {0}", signatureInfo.Location))
                    End If
                    ' print the signer contact info
                    If signatureInfo.ContactInfo IsNot Nothing Then
                        System.Console.WriteLine(String.Format("Contact Info: {0}", signatureInfo.SignerName))
                    End If
                    ' print the signing date
                    If signatureInfo.SigningTime <> System.DateTime.MinValue Then
                        System.Console.WriteLine(String.Format("Signig Date : {0}", signatureInfo.SigningTime.ToString("f")))
                    End If
    
                    ' get PKCS signature
                    Dim [error] As Boolean = False
                    Dim signature As Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignature = Nothing
                    Try
                        signature = signatureInfo.GetSignature()
                    Catch e As System.Exception
                        [error] = True
                        System.Console.WriteLine("PKCS signature parsing error: {0}", e.Message)
                    End Try
                    If [error] Then
                        Continue For
                    End If
    
                    ' print name of signature algorithm
                    System.Console.WriteLine(String.Format("Algorithm   : {0}", signature.SignatureAlgorithmName))
    
                    ' print information about signature certificate chain
                    System.Console.WriteLine("Sign certificate chain:")
                    Dim signCertChain As System.Security.Cryptography.X509Certificates.X509Certificate2() = signature.SigningCertificateChain
                    Dim padding As String = ""
                    For Each cert As System.Security.Cryptography.X509Certificates.X509Certificate2 In signCertChain
                        padding += "    "
                        System.Console.WriteLine("{0}Serial number: {1}", padding, cert.SerialNumber)
                        System.Console.WriteLine("{0}Issuer       : {1}", padding, cert.GetNameInfo(System.Security.Cryptography.X509Certificates.X509NameType.SimpleName, True))
                        System.Console.WriteLine("{0}Subject      : {1}", padding, cert.GetNameInfo(System.Security.Cryptography.X509Certificates.X509NameType.SimpleName, False))
                    Next
    
    
                    ' verify digital signature
                    VerifyDigitalSignature(signatureInfo, signature)
                End If
                System.Console.WriteLine()
            Next
        End Using
    End Sub
    
    ''' <summary>
    ''' Verifies the digital signature.
    ''' </summary>
    ''' <param name="signature">The signature.</param>
    ''' <param name="signatureInfo">The signature information.</param>
    ''' <returns><b>true</b> if signature is valid; otherwise, <b>false</b>.</returns>
    Public Shared Function VerifyDigitalSignature(signatureInfo As Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfSignatureInformation, signature As Vintasoft.Imaging.Pdf.Tree.DigitalSignatures.PdfPkcsSignature) As Boolean
        System.Console.WriteLine("Verifying signature...")
    
        Dim signatureVerifyResult As Boolean = False
        Dim embeddedTimestampVerifyResult As Boolean = False
        Dim certificateVerifyResult As Boolean = False
        Dim embeddedTimestampCertificateVerifyResult As Boolean = False
        Dim signatureCoversWholeDocument As Boolean = False
        Dim certificateChain As System.Security.Cryptography.X509Certificates.X509Chain = Nothing
        Dim timestampCertificateChain As System.Security.Cryptography.X509Certificates.X509Chain = Nothing
    
    
        ' verify signature
    
        Try
            ' check that signature covers the whole document
            signatureCoversWholeDocument = signatureInfo.SignatureCoversWholeDocument()
    
            ' verify PKCS signature
            signatureVerifyResult = signature.VerifySignature()
    
            ' if signature has embedded timestamp
            If signature.HasEmbeddedTimeStamp Then
                ' verify embedded timestamp
                embeddedTimestampVerifyResult = signature.VerifyTimestamp()
            End If
    
            ' build and verify certificate chain
            certificateChain = New System.Security.Cryptography.X509Certificates.X509Chain()
            certificateVerifyResult = certificateChain.Build(signature.SigningCertificate)
    
            ' if signature has embedded timestamp
            If signature.HasEmbeddedTimeStamp Then
                ' build and verify timestamp certificate chain
                timestampCertificateChain = New System.Security.Cryptography.X509Certificates.X509Chain()
                embeddedTimestampCertificateVerifyResult = certificateChain.Build(signature.TimestampCertificate)
    
            End If
        Catch verificationException As System.Exception
            System.Console.WriteLine("Verification failed: {0}", verificationException.Message)
            Return False
        End Try
    
        Dim pageContentModified As Boolean = False
        Dim subsequentChangesMessage As String = ""
        ' if PKCS signature verification is passed AND signature does not cover the whole document
        If signatureVerifyResult AndAlso Not signatureCoversWholeDocument Then
            Try
                ' if signature has revision info
                If signatureInfo.SignedRevision IsNot Nothing Then
                    ' check subsequent changes
                    Using documentChanges As Vintasoft.Imaging.Pdf.PdfDocumentRevisionComparer = signatureInfo.GetDocumentChanges()
                        ' check subsequent changes in pages content
                        pageContentModified = documentChanges.HasModifiedPages
    
                        ' build subsequent changes message
                        If documentChanges.ChangedPageContents.Count > 0 Then
                            subsequentChangesMessage += String.Format("{0} page(s) modified; ", documentChanges.ChangedPageContents.Count)
                        End If
                        If documentChanges.AddedPages.Count > 0 Then
                            subsequentChangesMessage += String.Format("{0} page(s) added; ", documentChanges.AddedPages.Count)
                        End If
                        If documentChanges.RemovedPages.Count > 0 Then
                            subsequentChangesMessage += String.Format("{0} page(s) removed; ", documentChanges.RemovedPages.Count)
                        End If
                        If documentChanges.RemovedAnnotations.Count > 0 Then
                            subsequentChangesMessage += String.Format("annotations(s) on {0} page(s) removed; ", documentChanges.RemovedAnnotations.Count)
                        End If
                        If documentChanges.RemovedAnnotations.Count > 0 Then
                            subsequentChangesMessage += String.Format("removed annotation(s) on {0} page(s); ", documentChanges.RemovedAnnotations.Count)
                        End If
                        If documentChanges.AddedAnnotations.Count > 0 Then
                            subsequentChangesMessage += String.Format("added annotation(s) on {0} page(s); ", documentChanges.AddedAnnotations.Count)
                        End If
                        If documentChanges.ChangedAnnotations.Count > 0 Then
                            subsequentChangesMessage += String.Format("changed annotation(s) on {0} page(s); ", documentChanges.ChangedAnnotations.Count)
                        End If
                        If documentChanges.MiscellaneousChanges.Count > 0 Then
                            subsequentChangesMessage += String.Format("miscellaneous changes: {0}; ", documentChanges.MiscellaneousChanges.Count)
                        End If
                    End Using
                End If
            Catch verificationException As System.Exception
                System.Console.WriteLine("Verification failed: {0}", verificationException.Message)
                Return False
            End Try
        End If
    
        ' print signature verification result
    
        ' if PKCS signature verification is failed OR
        ' signature does not cover the whole document AND page(s) content is modified
        If Not signatureVerifyResult OrElse (Not signatureCoversWholeDocument AndAlso pageContentModified) Then
            System.Console.WriteLine("Signature is INVALID.")
        ' if certificate verification is failed
        ElseIf Not certificateVerifyResult OrElse (signature.HasEmbeddedTimeStamp AndAlso (Not embeddedTimestampCertificateVerifyResult OrElse Not embeddedTimestampVerifyResult)) Then
            System.Console.WriteLine("Signature validity is UNKNOWN.")
        Else
            System.Console.WriteLine("Signature is VALID.")
        End If
    
    
        ' print signature verification details
    
        ' if signature verification is successful
        If signatureVerifyResult Then
            ' if signature covers the whole document
            If signatureCoversWholeDocument Then
                System.Console.WriteLine("    Signature verification: Document has not been modified since this signature was applied.")
            Else
                ' if signature does NOT cover the whole document
                If pageContentModified Then
                    System.Console.WriteLine("    Signature verification: Document has been modified or corrupted since it was signed.")
                    System.Console.WriteLine(String.Format("    Subsequent changes: {0}.", subsequentChangesMessage))
                ElseIf subsequentChangesMessage <> "" Then
                    System.Console.WriteLine("    Signature verification: The revision of the document that was covered by this signature has not been altered; however, there have been subsequent changes to the document.")
                    System.Console.WriteLine(String.Format("    Subsequent changes: {0}.", subsequentChangesMessage))
                Else
                    System.Console.WriteLine("    Signature verification: Document has not been modified since this signature was applied.")
                End If
            End If
        Else
            ' if signature verification is NOT successful
            System.Console.WriteLine("    Signature verification: Document has been modified or corrupted since it was signed.")
        End If
    
        ' if signature has embedded timestamp
        If signature.HasEmbeddedTimeStamp Then
            If embeddedTimestampVerifyResult Then
                System.Console.WriteLine("    Timestamp verification: Timestamp is valid.")
            Else
                System.Console.WriteLine("    Timestamp verification: Timestamp is valid.")
            End If
        End If
    
    
        ' print certificate verification details
    
        ' if certificate chain is present
        If certificateChain IsNot Nothing Then
            ' if certificate verification is successful
            If certificateVerifyResult Then
                System.Console.WriteLine("    Certificate verification: Signer's certificate is valid.")
            Else
                ' if certificate verification is NOT successful
                ' print certificate verification status
                System.Console.WriteLine("    Certificate verification: Signer's certificate is invalid:")
                For Each status As System.Security.Cryptography.X509Certificates.X509ChainStatus In certificateChain.ChainStatus
                    System.Console.Write(String.Format("        {0}: {1}", status.Status, status.StatusInformation))
                Next
            End If
        End If
    
        ' if timestamp certificate chain is present
        If timestampCertificateChain IsNot Nothing Then
            ' if timestamp certificate verification is successful
            If embeddedTimestampCertificateVerifyResult Then
                System.Console.WriteLine("    Timestamp certificate verification: Signer's certificate is valid.")
            Else
                ' if timestamp certificate verification is NOT successful
                ' print certificate verification status
                System.Console.WriteLine("    Timestamp certificate verification: Signer's certificate is invalid:")
                For Each status As System.Security.Cryptography.X509Certificates.X509ChainStatus In timestampCertificateChain.ChainStatus
                    System.Console.Write(String.Format("        {0}: {1}", status.Status, status.StatusInformation))
                Next
            End If
        End If
    
        ' if signature is not verified
        If Not signatureVerifyResult Then
            Return False
        End If
    
        ' if signature does NOT cover the whole document and page content was modified
        If Not signatureCoversWholeDocument AndAlso pageContentModified Then
            Return False
        End If
    
        ' if signature certificate is NOT verified
        If Not certificateVerifyResult Then
            Return False
        End If
    
        If signature.HasEmbeddedTimeStamp Then
            ' if timestamp is NOT verified
            If Not embeddedTimestampVerifyResult Then
                Return False
            End If
    
            ' if timestamp certifiacet is NOT verified
            If Not embeddedTimestampCertificateVerifyResult Then
                Return False
            End If
        End If
    
        ' sigature is VALID
        Return True
    End Function
    


    ВАЖНО! Проверка сертификата будет выполнена успешно только в том случае, если сертификат добавлен в список доверенных корневых сертификатов текущего пользователя Windows. Подробнее о том, как управлять доверенными корневыми сертификатами, вы можете прочитать здесь: https://technet.microsoft.com/en-us/library/cc754841.aspx .


    Удаление цифровой подписи из PDF документа

    Чтобы удалить подпись из PDF документа, необходимо выполнить следующие действия:
    Вот C#/VB.NET код, который демонстрирует, как удалить подпись из PDF документа:
    /// <summary>
    /// Removes all digital signatures from PDF document.
    /// </summary>
    /// <param name="pdfFilename">The filename of PDF document.</param>
    public static void RemoveDigitalSignaturesFromPdfDocument(string pdfFilename)
    {
        // open PDF document
        using (Vintasoft.Imaging.Pdf.PdfDocument document =
            new Vintasoft.Imaging.Pdf.PdfDocument(pdfFilename))
        {
            // if PDF document has PDF interactive form
            if (document.InteractiveForm != null)
            {
                // get reference to the interactive form of PDF document
                Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfDocumentInteractiveForm form =
                    document.InteractiveForm;
    
                // get all signature fields of PDF document
                Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfInteractiveFormSignatureField[] signatureFields =
                    form.GetSignatureFields();
    
                // for each signature fields
                foreach (Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfInteractiveFormField field in signatureFields)
                {
                    // remove signature field
                    field.Remove();
                }
    
                // pack PDF document
                document.Pack();
            }
        }
    }
    
    ''' <summary>
    ''' Removes all digital signatures from PDF document.
    ''' </summary>
    ''' <param name="pdfFilename">The filename of PDF document.</param>
    Public Shared Sub RemoveDigitalSignaturesFromPdfDocument(pdfFilename As String)
        ' open PDF document
        Using document As New Vintasoft.Imaging.Pdf.PdfDocument(pdfFilename)
            ' if PDF document has PDF interactive form
            If document.InteractiveForm IsNot Nothing Then
                ' get reference to the interactive form of PDF document
                Dim form As Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfDocumentInteractiveForm = document.InteractiveForm
    
                ' get all signature fields of PDF document
                Dim signatureFields As Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfInteractiveFormSignatureField() = form.GetSignatureFields()
    
                ' for each signature fields
                For Each field As Vintasoft.Imaging.Pdf.Tree.InteractiveForms.PdfInteractiveFormField In signatureFields
                    ' remove signature field
                    field.Remove()
                Next
    
                ' pack PDF document
                document.Pack()
            End If
        End Using
    End Sub