AlexZ 发表于 2020-8-24 23:43:54

利用 GcExcel 在 C#中的Excel文件中分配和验证数字签名

本帖最后由 AlexZ 于 2020-8-24 23:51 编辑

在当前的数字环境中,传统的签名和认证文档正在迅速被数字签名所取代。数字签名是对数字信息(例如电子邮件消息,电子文档等)进行身份验证的电子加密认证标记。简而言之,数字签名是一种电子指纹,用于确认签名者的身份和文件的真实性。支持数字签名正成为数字文档中的标准。Excel电子表格中的数字签名支持在新版本中,GcExcel允许用户对Excel文件进 行数字签名以确保内容的真实性。该库使用IWorkbook.Signatures和IWorksheet.Shapes属性在Excel电子表格中支持数字签名。GcExcel支持以两种形式将数字签名添加到Excel中,既可以是实际签名,也可以是“签名行”。签名是嵌入到文档中的数字证书(PFX / PKCS12)的实际副本。当Excel文档中添加了签名时,在不使该签名无效的情况下,不允许对文档进行任何编辑。签名行在外观上类似于可能出现在打印文档中的典型签名占位符。将签名行插入Excel文件时,作者可以指定有关预期签名者的信息(名称,标题和电子邮件地址),以及有关签名者。将文件的电子副本发送给预期的签名者时,他们可以看到签名行和要求签名的通知。
GcExcel提供了几种用于创建数字签名的选项。您可以添加不可见的签名,添加/删除/更新签名行,将签名的工作簿导出为PDF以及验证签名。GcExcel支持的数字签名功能除了将数字签名添加到Excel工作簿之外,GcExcel还支持许多其他功能。支持的功能可以分为三类。此类别中的功能演示了Excel电子表格的签名。您可以使用以下方法在GcExcel中对Excel文件进​​行签名:添加不可见的签名要对工作簿进行签名,请首先使用ISignatureSet.AddNonVisibleSignature方法创建签名,然后使用SignatureDetails类输入签名详细信息。定义签名后,请通过X509Certificate2类加载证书,使用ISignature.Sign方法创建签名包,最后通过调用IWorkbook.Save方法来提交签名。//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");签名行Excel电子表格包含签名行时,它会显示一个通知,以对文档进行签名并提供签名详细信息。使用GcExcel,可以完全用代码执行此任务。也就是说,GcExcel将使用签名行加载Excel文件,启用输入签名详细信息,并使用代码对文档进行签名。
要对签名行进行签名,请如上所述将签名添加到Excel电子表格,然后调用ISignature.Sign方法。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");反签工作簿
若要对签名进行反签名(将签名添加到已经签名的工作簿中),请首先创建一个签名行和一个如上所述的签名,然后使用具有相同证书的ISignature.Countersign方法对签名进行反签名。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.Countersign(cert);

// Commit signature
workbook.Save("CountersignSignature.xlsx");管理签名GcExcel还可以管理签名(当Excel文件已经通过签名或签名行进行签名时,可以对其进行修改,检索和验证)。以下是GcExcel支持的各种管理签名的操作:
添加签名行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");复制签名行可以将添加到文档的签名行复制到另一个范围或工作表。使用IRange.Copy,IShape.Duplicate或IWorksheet.Copy方法可以将签名行复制到另一个范围或工作表。// 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");切签名线
要将签名行剪切到另一个范围,请使用IRange.Cut方法。// 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");删除签名行
使用GcExcel,也可以通过删除签名来完全删除签名行。若要删除签名行,请使用ISignature.Delete或IShape.Delete方法。// 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");移动签名行
使用IShape.Top和IShape.Left属性将签名行移动到另一个范围或工作表。// Move signature line
signatureShinzo.SignatureLineShape.Top += 100;
signatureShinzo.SignatureLineShape.Left += 50;

//save to an excel file
workbook.Save("movesignaturelines.xlsx");验证签名
您可以在Excel电子表格中验证现有签名。这可以使用ISignature.IsSigned和ISignature.IsValid属性来完成。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.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);
}列表签名
添加多个签名行后,请使用IWorkbook.Signatures列出带有索引或枚举器的签名行。// List signatures with indexes
for (var i = 0; i < signatures.Count; i++)
{
    var signature = signatures;
    // 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");将签名的Excel电子表格导出为PDF
使用GcExcel,您可以将签名行签名的Excel电子表格导出为PDF格式。要导出,请使用IWorkbook.Save方法。workbook.Open(GetResourceStream(@"xlsx\Signature.xlsx"));
workbook.Signatures.SkipCertificateValidationOnExporting = false;

//save to a pdf file
workbook.Save("exportsignaturelinetopdf.pdf");让我们考虑一些常见情况,并了解如何使用GcExcel添加/管理数字签名。数字签名Excel文件的步骤让我们构建一个Visual Studio .NET Core应用程序并实现以下两种情况:如何签署Excel档案?这是最常见的情况,其中要求对现有的Excel文件进​​行签名以确认Excel电子表格的真实性。这是通过将数字签名(不可见)添加到Excel文件来完成的。步骤1.安装
[*]在您的.Net Core Console应用程序中,右键单击“依赖项”,然后选择“管理NuGet程序包”。
[*]在“浏览”选项卡下,搜索“ GrapeCity.Documents.Excel”,然后单击“安装”。
[*]在安装过程中,您将收到两个确认对话框:“预览更改”和“许可接受”,分别单击“确定”和“我同意”以继续。

步骤2.设置C#项目添加名称空间在程序文件中,导入以下名称空间。using GrapeCity.Documents.Excel;创建一个新的工作簿在主要功能中,添加以下代码以创建新的GcExcel工作簿。Workbook workbook = new Workbook();加载Excel工作簿
在主要功能中,添加以下代码以从项目资源中将Excel报告作为文件流加载。var assembly = typeof(DigitalSignaturesDemo_GcExcel.Program).GetTypeInfo().Assembly;
Stream signedFileStream = assembly.GetManifestResourceStream("DigitalSignaturesDemo_GcExcel.Resources.Financial Sample.xlsx");
workbook.Open(signedFileStream);创建一个看不见的签名在主函数中,调用AddNonVisibleSignature方法来创建一个新的不可见签名。ISignature signature = workbook.Signatures.AddNonVisibleSignature();定义签名详细信息
创建SignatureDetails类的实例,并设置其各种属性以定义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"
};加载证书使用X509Certificate2类加载证书。X509Certificate2 cert = new X509Certificate2("Resources/GPCTAdmin.pfx", "grapecity@123");签署Excel档案通过调用Sign .html)方法,使用加载的证书创建签名包,并为创建的不可见签名定义详细信息。signature.Sign(cert, details);提交签名要提交签名,请将工作簿另存为.xlsx或 .xlsm。
workbook.Save("SignWorkbook.xlsx");如何签署已经签署的Excel文件?另一个常见方案是在进行修改后对已经签名的Excel文件进​​行签名。修改文档后,现有签名将无效;因此,该文档需要重新签名。为此,请使用GcExcel添加不可见的数字签名。通过修改来签名已经签名的Excel文件的步骤涉及以前方案中的所有步骤以及一些其他步骤。在以前的场景中,我们直接向工作簿添加了签名。但是,在这种情况下,由于需要重新签名现有的Excel文件,因此我们需要使用XlsxOpenOptions类来确保以DigitalSignatureOnly模式打开该文件。必须以DigitalSignatureOnly模式打开Excel文件,因为如果没有仅数字签名模式,则在保存工作簿后将删除所有现有签名。除了上一个示例中提供的代码之外,在创建工作簿实例之后立即使用以下代码。XlsxOpenOptions openOption = new XlsxOpenOptions { DigitalSignatureOnly = true };
workbook.Open(signedFileStream, openOption);此过程从已经使用签名行签名的Excel中生成带有不可见签名的Excel文件。
页: [1]
查看完整版本: 利用 GcExcel 在 C#中的Excel文件中分配和验证数字签名