Skip to main content Skip to footer

Assign and Validate Digital Signatures in Excel Files in C#

In the current digital landscape, traditional signing and authenticating documents are quickly being replaced by digital signatures. A digital signature is an electronic, encrypted stamp of authentication on digital information, such as e-mail messages, electronic documents, etc.

Simply put, a digital signature is an electronic fingerprint that confirms the signer's identity and the authenticity of the document. Supporting digital signature is becoming a standard in digital documentation.

The GrapeCity Documents for Excel v3.2 release introduces support for digital signatures in Excel spreadsheets.

Digital Signature Support in Excel Spreadsheets

With the new release, GcExcel allows a user to digitally sign an Excel file to secure the content's authenticity. The library supports digital signature in the Excel spreadsheets using the IWorkbook.Signatures and IWorksheet.Shapes properties.

GcExcel enables adding a digital signature into Excel in two forms, either as an actual Signature or as a 'Signature Line.' A signature is an actual copy of the digital certificate (PFX/PKCS12) that gets embedded into the document. When an Excel document has a signature added to it, no edits are permitted to the document without invalidating that signature.

A signature line visually resembles a typical signature placeholder that might appear in a printed document.When a signature line is inserted into an Excel file, the author can specify information (name, title, and email address) about the intended signer, and instructions for the signer.

When an electronic copy of the file is sent to the intended signer, they can see the signature line and a notification that their signature is requested.

GcExcel provides several options for creating digital signatures. You can add invisible signatures, add/remove/update signature lines, export a signed workbook to PDF, and verify signatures.

Digital Signature Features Supported in GcExcel

Apart from adding digital signatures to the Excel workbook, GcExcel supports many additional features.

The features supported can be divided into three categories.

The features in this category demonstrate the signing of an Excel spreadsheet. You can use the following methods to sign an Excel file in GcExcel:

Add non-visible signature

To sign the workbook, first create a signature using the ISignatureSet.AddNonVisibleSignature method and input the signature details using SignatureDetails class. Once the signature is defined, load the certificate via X509Certificate2 class, create signature packet using ISignature.Sign method and finally commit the signature by invoking the IWorkbook.Save method.

//create a new workbook
var workbook = new GrapeCity.Documents.Excel.Workbook();

ISignature signature = workbook.Signatures.AddNonVisibleSignature();

// TODO: Use your information
var details = new SignatureDetails
{
    Address1 = "<your address>",
    Address2 = "<address 2>",
    SignatureComments = "Final",
    City = "<your city>",
    StateOrProvince = "<your state or province>",
    PostalCode = "<your postal code>",
    CountryName = "<your country or region>",
    ClaimedRole = "<your role>",
    CommitmentTypeDescription = "Approved",
    CommitmentTypeQualifier = "Final"
};

// TODO: Use your certificate
var cert = new X509Certificate2("<your certificate file>", "<your password>");

// TODO: Use your name or signature image
signature.Sign(cert, details);

// Commit signature
workbook.Save("SignWorkbook.xlsx");
Sign signature line

When an Excel spreadsheet contains a signature line, it displays a notification to sign the document and provide the signature details. Using GcExcel, it is possible to perform this task in code completely; that is, GcExcel will load the Excel file with the signature line, enable entering signature details, and sign the document using code.

To sign a signature line, add signature to the Excel spreadsheet as shown above and invoke the ISignature.Sign method.

ISignature signature = workbook.Signatures.AddSignatureLine(workbook.ActiveSheet, 100.0, 50.0);

// TODO: Use your information
ISignatureSetup setup = signature.Setup;
setup.ShowSignDate = true;
setup.AllowComments = true;
setup.SigningInstructions = "<your signing instructions>";
setup.SuggestedSigner = "<signer's name>";
setup.SuggestedSignerEmail = "example@microsoft.com";
setup.SuggestedSignerLine2 = "<signer's title>";

// TODO: Use your information
var details = new SignatureDetails
{
    Address1 = "<your address>",
    Address2 = "<address 2>",
    SignatureComments = "Final",
    City = "<your city>",
    StateOrProvince = "<your state or province>",
    PostalCode = "<your postal code>",
    CountryName = "<your country or region>",
    ClaimedRole = "<your role>",
    CommitmentTypeDescription = "Approved",
    CommitmentTypeQualifier = "Final"
};

// TODO: Use your certificate
var cert = new X509Certificate2("<your certificate file>", "<your password>");

// TODO: Use your name or signature image
signature.Sign(cert, "<your name>", details);

// Commit signature
workbook.Save("SignSignatureLine.xlsx");
Counter-sign workbook

To counter-sign a signature (add a signature to a workbook that is already signed), first create a signature line and a signature as above, then use ISignature.Countersign method with the same certificate to counter-sign the signature.

ISignature signature = workbook.Signatures.AddSignatureLine(workbook.ActiveSheet, 100.0, 50.0);

ISignatureSetup setup = signature.Setup;
setup.ShowSignDate = true;
setup.AllowComments = true;
setup.SigningInstructions = "<your signing instructions>";
setup.SuggestedSigner = "<signer's name>";
setup.SuggestedSignerEmail = "example@microsoft.com";
setup.SuggestedSignerLine2 = "<signer's title>";

var details = new SignatureDetails
{
    Address1 = "<your address>",
    Address2 = "<address 2>",
    SignatureComments = "Final",
    City = "<your city>",
    StateOrProvince = "<your state or province>",
    PostalCode = "<your postal code>",
    CountryName = "<your country or region>",
    ClaimedRole = "<your role>",
    CommitmentTypeDescription = "Approved",
    CommitmentTypeQualifier = "Final"
};

// Sign the workbook
var cert = new X509Certificate2("<your certificate file>", "<your password>");
signature.Sign(cert, "<your name>", details);

// Reopen the workbook
var ms = new MemoryStream();
workbook.Save(ms);
ms.Position = 0;
workbook.Open(ms);

// Modify
workbook.Worksheets["Sheet1"].Range["A1"].Value = "Modified";

// Countersign
workbook.Signatures[0].Countersign(cert);

// Commit signature
workbook.Save("CountersignSignature.xlsx");

Managing Signature

GcExcel also enables the management of signatures (when the Excel file is already signed either via signatures or signature line, it is possible to modify, retrieve, and verify them). Below are the various operations supported by GcExcel to manage the signatures:

Add signature line
IWorksheet activeSheet = workbook.ActiveSheet;

ISignatureSetup setup = workbook.Signatures.AddSignatureLine(activeSheet, 100.0, 50.0).Setup;
setup.ShowSignDate = false;
setup.AllowComments = false;
setup.SigningInstructions = "Please check the content before signing.";
setup.SuggestedSigner = "Shinzo Nagama";
setup.SuggestedSignerEmail = "shinzo.nagama@ea.com";
setup.SuggestedSignerLine2 = "Commander (Balanced)";

//save to an excel file
workbook.Save("addsignaturelines.xlsx");
Copy signature line

The signature line added to the document can be copied to another range or worksheet. This is possible using the IRange.Copy, IShape.Duplicate or IWorksheet.Copy methods to copy signature line to another range or worksheet.

// Copy signature line with Range.Copy
IRange srcRange = activeSheet.Range["A1:I15"];
IRange destRange = activeSheet.Range["A16:I30"];
srcRange.Copy(destRange);

// Copy signature line with Shape.Duplicate
signature.SignatureLineShape.Duplicate();

// Copy signature line with Worksheet.Copy
activeSheet.Copy();

//save to an excel file
workbook.Save("copysignaturelines.xlsx");
Cut signature line

To cut a signature line to another range, use IRange.Cut method.

// Cut signature line with Range.Cut
IRange srcRange = activeSheet.Range["A1:I15"];
IRange destRange = activeSheet.Range["A16:I30"];
srcRange.Cut(destRange);

//save to an excel file
workbook.Save("cutsignaturelines.xlsx");
Delete signature line

With GcExcel, it is also possible to completely remove the signature line by deleting it. To delete the signature line, use ISignature.Delete or IShape.Delete methods.

// Create a new signature line and delete with Signature.Delete
ISignature signatureForTest = newSignatureLine();
signatureForTest.Delete();

// Create a new signature line and delete with Shape.Delete
signatureForTest = newSignatureLine();
IShape signatureLineShape = signatureForTest.SignatureLineShape;
signatureLineShape.Delete();

//save to an excel file
workbook.Save("deletesignaturelines.xlsx");
Move signature line

Use IShape.Top and IShape.Left properties to move signature lines to another range or worksheet.

// Move signature line
signatureShinzo.SignatureLineShape.Top += 100;
signatureShinzo.SignatureLineShape.Left += 50;

//save to an excel file
workbook.Save("movesignaturelines.xlsx");
Verify signature

You can verify an existing signature in an Excel Spreadsheet. This can be done using ISignature.IsSigned and ISignature.IsValid properties.

ISignatureSet signatures = workbook.Signatures;

bool signed = false;
bool valid = false;
X509Certificate2 certificate = null;

// Verify the first signed signature
foreach (var signature in signatures)
{
    if (signature.IsSigned)
    {
        signed = true;
        certificate = signature.Details.SignatureCertificate;
        // Verify signature
        valid = signature.IsValid;
        break;
    }
}

// Verify certificate
if (certificate != null)
{
    var status = X509ChainStatusFlags.NoError;

    // build the certificate chain
    var chain = new X509Chain();
    bool certValid = chain.Build(certificate);

    // inspect the results
    if (!certValid)
    {
        var chainStatus = chain.ChainStatus;
        for (var i = 0; i < chainStatus.Length; i++)
        {
            status |= chainStatus[i].Status;
        }
    }

    // Extract the certificate verification result.
    // You can write them to trace listeners or draw them on your screen to observe the result.
    var isCertificateExpired = status.HasFlag(X509ChainStatusFlags.NotTimeValid);
    var isCertificateRevoked = status.HasFlag(X509ChainStatusFlags.Revoked);
    var isCertificateUntrusted = status.HasFlag(X509ChainStatusFlags.UntrustedRoot);
}
List signature

Once multiple signature lines are added, use IWorkbook.Signatures to list signature lines with index or enumerator.

// List signatures with indexes
for (var i = 0; i < signatures.Count; i++)
{
    var signature = signatures[i];
    // Insert your code here
}

// List signatures with enumerator
foreach (var signature in signatures)
{
    // Insert your code here
}

//save to an excel file
workbook.Save("listsignaturelines.xlsx");

Exporting Signed Excel Spreadsheet to PDF

Using GcExcel, you can export the Excel spreadsheet signed by signature line, to PDF format. To export use IWorkbook.Save method.

workbook.Open(GetResourceStream(@"xlsx\Signature.xlsx"));
workbook.Signatures.SkipCertificateValidationOnExporting = false;

//save to a pdf file
workbook.Save("exportsignaturelinetopdf.pdf");

Let's consider a few common situations and see how to add/manage digital signatures using GcExcel.

Steps to Digitally Sign Excel Files

Let's build a Visual Studio .NET Core application and implement the following two scenarios:

How to Sign the Excel File?

It's the most common scenario, where the requirement is to sign an existing Excel file in order to confirm the authenticity of the Excel spreadsheet. This is done by adding a digital signature (invisible) to the Excel file.

Step 1. Installation

Download and unzip the full demonstration package - you can load and run it if you would like. However, for this step by step example, we will only need to bring over the "Resources" folder to the C# .NET Core Console application you create.

  • Create a new C# .NET Core Console application.
  • In your .Net Core Console application, right-click ‘Dependencies,’ and select ‘Manage NuGet Packages.’
  • Under the ‘Browse’ tab search for ‘GrapeCity.Documents.Excel’ and click Install.
  • While installing, you’ll receive two confirmation dialogs: ‘Preview Changes’ and ‘License Acceptance,’ click ‘Ok’, and ‘I Agree’ respectively to continue.
  • Rename the namespace of the new project to "DigitalSignaturesDemo_GcExcel".
  • Create a resource folder in the project (or drag and drop the resource folder from the unzipped demo area). If you do the latter, skip the next step.
  • Copy 3 files from the full demo resource folder to your applications Resource folder: FinancialReport.xlsx, GPTCAdmin.pfx, and SignedFinancialReport.xlsx.
  • In VS, under the resources folder, select the GPTCAdmin.pfx file, change the "Build Action" property to "Content" and the "Copy to Output Directory" property to "Copy Always".
  • In VS, under the resources folder, select the FinancialReport.xlsx file, change the "Build Action" Property to "Embedded Resource", and ensure the "Copy to Output Directory" property is set to "Do not copy".
Step 2. Setup C# Project
Add namespace

In the Program file, import following namespace.

using GrapeCity.Documents.Excel;

Create a new workbook

In the main function, add following code to create a new GcExcel workbook.

Workbook workbook = new Workbook();

Load Excel workbook

In the main function, add following code to load Excel report as file stream from project's Resources.

var assembly = typeof(DigitalSignaturesDemo_GcExcel.Program).GetTypeInfo().Assembly;
Stream signedFileStream = assembly.GetManifestResourceStream("DigitalSignaturesDemo_GcExcel.Resources.Financial Sample.xlsx");
workbook.Open(signedFileStream);
Create an invisible signature

In the main function, invoke AddNonVisibleSignature method to create a new invisible signature.

ISignature signature = workbook.Signatures.AddNonVisibleSignature();

Define signature details

Create an instance of SignatureDetails class and set its various properties to define the Signature Details.

SignatureDetails details = new SignatureDetails
{
    Address1 = "GrapeCity India Pvt Ltd",
    Address2 = "A-15, Sector 62",
    SignatureComments = "Final",
    City = "Noida>",
    StateOrProvince = "Uttar Pradesh",
    PostalCode = "201307",
    CountryName = "India",
    ClaimedRole = "Software Engineer",
    CommitmentTypeDescription = "Approved",
    CommitmentTypeQualifier = "Final"
};
Load certificate

Load the certificate using the X509Certificate2 class.

X509Certificate2 cert = new X509Certificate2("Resources/GPCTAdmin.pfx", "grapecity@123");
Sign the Excel file

Create a signature packet with the loaded certificate and the details defines for the invisible signature created, by invoking Sign. html method.

signature.Sign(cert, details);

Commit the signature

To commit the signature, save the workbook as .xlsx or .xlsm.

workbook.Save("SignWorkbook.xlsx");

How to Sign an Excel file that has already been signed?

Another common scenario is to sign an already signed Excel file after making modifications. When a document is modified, the existing signature becomes invalid; therefore, the document needs to be re-signed.

To do this, add an invisible digital signature using GcExcel. The steps to sign an already signed Excel file with modifications involve all the steps in the previous scenario with a few additional steps.

In the previous scenario, we directly added a signature to the Workbook. However, in this scenario, since the demand is to re-sign an existing Excel file, we need to use the XlsxOpenOptions class to ensure that the file is opened in DigitalSignatureOnly mode.

Opening the Excel file in DigitalSignatureOnly mode is necessary, as without the digital signature only mode, all existing signatures will be removed after saving the workbook.

Use the following code just after creating the workbook instance, in addition to the code presented in the previous example.

XlsxOpenOptions openOption = new XlsxOpenOptions { DigitalSignatureOnly = true };
workbook.Open(signedFileStream, openOption);

This process generates an Excel file with invisible signature from an Excel that was already signed with signature line.

Download Demo

Visit Help: .NET | JAVA

Demo: .NET | JAVA for more details.

Ruchir Agarwal

comments powered by Disqus