Skip to main content
All docs
V23.2

DocumentSigner Class

Allows you to sign Office documents and validate signatures.

You need an active DevExpress Office File API Subscription or DevExpress Universal Subscription to use these methods in production code.

Namespace: DevExpress.Office.DigitalSignatures

Assembly: DevExpress.Docs.v23.2.dll

NuGet Package: DevExpress.Document.Processor

Declaration

public class DocumentSigner

Remarks

To use the DocumentSigner class methods, add a reference to the DevExpress.Docs.v23.2.dll assembly. If you use this assembly in production code, a license for the DevExpress Office File API or DevExpress Universal Subscription is required. For more information, refer to the following page: DevExpress Subscription Plans.

Sign Documents

Use the DocumentSigner.Sign method to sign documents and save the result. You can use XAdES-BES and XAdES-T signatures with X.509 certificates. The following formats are available:

  • Microsoft Word
    • Open XML (DOCX, DOTX, DOTM, DOCM)
    • 97-2003 (DOC, DOT)
  • Microsoft Excel
    • Open XML (XLSX, XLTX, XLSM)
    • 97-2003 binary file (XLS, XLT)
  • Microsoft PowerPoint
    • PPTX, PPT

The SignatureOptions class object allows you to specify validation data (certificate, hash algorithm, timestamp, etc.). Pass the SignatureInfo object to define the signer information.

The options and signatureInfo parameters cannot be null.

The code sample below signs and saves a Word and Excel document:

using DevExpress.Office.DigitalSignatures;
using System;
using System.Diagnostics;
using System.Security.Cryptography.X509Certificates;

static void Main(string[] args)
{
    //Sign a workbook:
    SignDocument("Template.xlsx", "Workbook_signed.xlsx");

    //Sign a document:
    SignDocument("Template.docx", "Template_signed.docx");
}
static void SignDocument(string path, string output)
{
    DocumentSigner documentSigner = new DocumentSigner();
    documentSigner.Sign(path, output,
     CreateSignatureOptions(), CreateSignatureInfo());
}

//Specify a signature certificate and digest method:
static SignatureOptions CreateSignatureOptions()
{
    X509Certificate2 certificate = new X509Certificate2("Certificate/SignDemo.pfx", "dxdemo");
    Uri tsaServer = new Uri("https://freetsa.org/tsr");
    SignatureOptions options = new SignatureOptions();
    options.Certificate = certificate;
    if (tsaServer != null)
        options.TsaClient = new TsaClient(tsaServer, HashAlgorithmType.SHA256);

    //In this example, certificate validation is skipped
    options.SignatureFlags &= ~SignatureFlags.ValidateCertificate;
    options.CertificateKeyUsageFlags = X509KeyUsageFlags.None;
    options.DigestMethod = HashAlgorithmType.SHA256;

    X509ChainPolicy policy = new X509ChainPolicy();
    policy.RevocationMode = X509RevocationMode.NoCheck;
    policy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
    policy.VerificationFlags |= X509VerificationFlags.AllowUnknownCertificateAuthority |
        X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown;
    options.CertificatePolicy = policy;
    options.TimestampCertificatePolicy = policy;
    return options;
}

//Specify signer information:
static SignatureInfo CreateSignatureInfo()
{
    SignatureInfo signatureInfo = new SignatureInfo();
    signatureInfo.CommitmentType = CommitmentType.ProofOfApproval;
    signatureInfo.Time = DateTime.UtcNow;
    signatureInfo.ClaimedRoles.Clear();
    signatureInfo.ClaimedRoles.Add("Sales Representative");
    signatureInfo.Comments = "Demo Digital Signature";

    return signatureInfo;
}

Validate Signatures

Call the DocumentSigner.Validate method to validate document signatures. The SignatureValidationOptions object allows you to specify signature validation options. Use the SignatureValidationOptions.ValidationFlags property to exclude validation steps.

private static void ValidateSignature(string path)
{
    DocumentSigner validator = new DocumentSigner();

    //Specify validation options
    //In this example, certificate validation
    //is skipped
    SignatureValidationOptions validationOptions = new SignatureValidationOptions();
    validationOptions.ValidationFlags = ~ValidationFlags.ValidateSignatureCertificate & ~ValidationFlags.ValidateTimestampCertificate;

    //Validate the signature:
    PackageSignatureValidation signatureValidation = validator.Validate(path, validationOptions);
    AnalyzeValidationResult(signatureValidation);

}

Validation Process

The Validate method returns the PackageSignatureValidation instance that contains validation information. Check the PackageSignatureValidation.Result and PackageSignatureValidation.ResultMessage properties to determine whether the signature is valid.

Note

Make sure that the signature certificate is registered on your machine. Otherwise, the signature is invalid.

If the document is not signed, the PackageSignatureValidation.Result property returns SignaturesNotFound. If the PackageSignatureValidation.Result property returns Invalid or PartiallyValid, check the PackageSignatureValidation.Items property to obtain a list of items with detailed validation information. The number of SignatureValidationInfo objects in the list is equal to the number of signatures.

The table below lists API used to obtain information:

Property Description
SignatureValidationInfo.PassedChecks Returns verification types the signature passed.
SignatureValidationInfo.PassedCheckDetails Obtains information about passed verifications.
SignatureValidationInfo.FailedChecks Returns verification types the signature did not pass.
SignatureValidationInfo.FailedCheckDetails Retrieves information about failed verifications.
SignatureValidationInfo.CheckDetails Gets information about all verifications.

The code sample below analyzes the validation result and shows information in the console:

private static void AnalyzeValidationResult(PackageSignatureValidation signatureValidation)
{
    string validationMessage = signatureValidation.ResultMessage;

    //Check validation result and show information in the console:
    switch (signatureValidation.Result)
    {
        case PackageSignatureValidationResult.Valid:
            Console.WriteLine(validationMessage); Console.ReadKey();
            Process.Start(output);
            break;

        case PackageSignatureValidationResult.SignaturesNotFound:
            Console.WriteLine(validationMessage);
            break;

        case PackageSignatureValidationResult.Invalid:
        case PackageSignatureValidationResult.PartiallyValid:
            var failedCheckDetails = signatureValidation.Items[0].FailedCheckDetails;
            Console.WriteLine(validationMessage);
            int i = 1;
            foreach (SignatureCheckResult checkResult in failedCheckDetails)
            {
                Console.WriteLine(String.Format("Validation details {0}: \r\n" +
                    "{1} failed, Info: {2} \r\n", i, checkResult.CheckType, checkResult.Info));
                i++;
            }
            Console.ReadKey();
            break;
    }
}

Remove Signatures

Utilize the DocumentSigner.RemoveSignatures method to clear signatures from a document and save the result.

static void Main(string[] args)
{
    ClearSignatures("Template_signed.docx", @"D:/Template_cleared.docx");
    ClearSignatures("Template_signed.xlsx", @"D:/Template_cleared.xlsx");
}

  private static void ClearSignatures(string path, string output)
  {
      DocumentSigner remover = new DocumentSigner();
      remover.RemoveSignatures(path, output);
      Process.Start(output);
  }

Inheritance

Object
DocumentSigner
See Also