C#和vb.net实现PDF 添加可视化和不可见数字签名

C# 和 VB.net 都可以使用 iTextSharp 库来实现 PDF 文件添加数字签名。数字签名可以是可视化的,也可以是不可见的。

以下是实现 PDF 添加数字签名的完整攻略:

步骤 1:引入 iTextSharp 库

在项目中引入 iTextSharp 库。通常会从 NuGet 软件包管理器中安装该库,或者从官方网站 https://github.com/itext/itextsharp 下载。

步骤 2:创建签名类

首先,创建一个签名类,该类继承了 IExternalSignature 接口,实现了 Sign 方法。在 Sign 方法中,我们可以使用数字证书对 PDF 签名,并将签名数据写入 PDF 文件。

public class MyExternalSignature : IExternalSignature
{
    private string _pkcs12FilePath;
    private string _password;

    public MyExternalSignature(string pkcs12FilePath, string password)
    {
        _pkcs12FilePath = pkcs12FilePath;
        _password = password;
    }

    public string GetHashAlgorithm()
    {
        return DigestAlgorithms.SHA256;
    }

    public string GetEncryptionAlgorithm()
    {
        return EncryptionAlgorithm.RSA;
    }

    public byte[] Sign(byte[] message)
    {
        X509Certificate2 pkcs12 = new X509Certificate2(_pkcs12FilePath, _password);
        RSACryptoServiceProvider key = (RSACryptoServiceProvider)pkcs12.PrivateKey;
        Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { DotNetUtilities.FromX509Certificate(pkcs12) };
        IExternalSignature signature = new PrivateKeySignature(key, GetHashAlgorithm());
        return signature.Sign(message);
    }
}

步骤 3:创建 PDF 签名

接下来,我们需要创建 PDF 签名。以下是一个简单的方法,它接受输入文件名,数字证书和输出文件名。其中,数字证书作为参数传递给 MyExternalSignature 类的构造函数。

private void SignPdf(string inputFilePath, string certFilePath, string certPassword, string outputFilePath)
{
    var reader = new PdfReader(inputFilePath);
    var stamper = PdfStamper.CreateSignature(reader, new FileStream(outputFilePath, FileMode.Create), '\0');
    var appearance = stamper.SignatureAppearance;
    appearance.SetVisibleSignature("Signed by me");
    appearance.Reason = "Signed by me";
    appearance.Location = "Shanghai";
    var externalSignature = new MyExternalSignature(certFilePath, certPassword);
    MakeSignature.SignDetached(appearance, externalSignature, new Org.BouncyCastle.X509.X509Certificate[] { });
}

示例 1: 可视化签名

以下是一个多页 PDF 文件的示例。此示例在第一页顶部添加了可视化签名。

var inputFilePath = "input.pdf";
var outputFilePath = "output.pdf";
var certFilePath = "cert.pfx";
var certPassword = "password";

var reader = new PdfReader(inputFilePath);
var stamper = PdfStamper.CreateSignature(reader, new FileStream(outputFilePath, FileMode.Create), '\0');

var signaturePage = 1;
var pageSize = reader.GetPageSizeWithRotation(signaturePage);
var x = pageSize.Left + 10;
var y = pageSize.Top - 10;
var signatureField = PdfFormField.CreateSignature(stamper.Writer);
signatureField.FieldName = "Signature1";
signatureField.SetWidget(new iTextSharp.text.Rectangle(x, y, x + 200, y + 50), PdfAnnotation.HighlightInvert);
signatureField.SetPage(signaturePage);
signatureField.MKBorderColor = BaseColor.GRAY;
signatureField.MKBackgroundColor = BaseColor.LIGHT_GRAY;
stamper.AddAnnotation(signatureField, signaturePage);

var appearance = stamper.SignatureAppearance;
appearance.SetVisibleSignature(new Rectangle(x, y, x + 200, y + 50), signaturePage, "Signed by me");
appearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.GRAPHIC;
appearance.CertificationLevel = PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED;
appearance.Reason = "Signed by me";
appearance.Location = "Shanghai";

var externalSignature = new MyExternalSignature(certFilePath, certPassword);
MakeSignature.SignDetached(appearance, externalSignature, new Org.BouncyCastle.X509.X509Certificate[] { });
stamper.Close();

此示例首先创建了一个 signatureField 对象并将其添加到第一页的指定位置。然后,它设置了可视化签名的外观,并使用 MakeSignature.SignDetached 方法进行签名。

示例 2: 不可视化签名

以下示例使用不可视化签名签署 PDF 文件。

var inputFilePath = "input.pdf";
var outputFilePath = "output.pdf";
var certFilePath = "cert.pfx";
var certPassword = "password";

var externalSignature = new MyExternalSignature(certFilePath, certPassword);

using (Stream input = new FileStream(inputFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
using (Stream output = new FileStream(outputFilePath, FileMode.Create, FileAccess.Write, FileShare.None))
{
    var signer = new PdfSigner(new PdfReader(input), output, new StampingProperties().UseAppendMode());
    signer.SetCertificationLevel(PdfSigner.NOT_CERTIFIED);
    signer.SignExternalContainer(externalSignature, 8192);
    signer.Document.Close();
}

此示例使用 PdfSigner 类来签署文档。它设置了不可视化签名,并最终使用 externalSignature 对象来签署 PDF 文件。

希望这个攻略对您有所帮助!

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#和vb.net实现PDF 添加可视化和不可见数字签名 - Python技术站

(0)
上一篇 2023年5月31日
下一篇 2023年5月31日

相关文章

  • C#读取数据库返回泛型集合详解(DataSetToList)

    C#读取数据库返回泛型集合是一种常见的数据访问方式,可以快速、高效地将数据库里的数据以泛型集合的方式返回给程序,本文将详细讲解如何使用DataSetToList实现这一功能。 准备工作 在使用DataSetToList读取数据库前,需要进行一些准备工作,具体如下: 1.引用相关命名空间 在代码文件中,需要引用以下命名空间: using System.Data…

    C# 2023年5月31日
    00
  • C#中Datetimepicker出现问题的解决方法

    C# 中的 DateTimePicker 是一个常用的日期选择控件,但有时用户在操作时会出现一些问题,本文将介绍如何解决这些问题。 问题一:日期选择后无法正确显示 有时候用户会发现在 DateTimePicker 中选择的日期和实际显示的日期不一致,甚至会显示错误的日期。这通常是因为 DateTimePicker 控件的 Value 属性被修改了。为了解决这…

    C# 2023年5月15日
    00
  • C# Linq的OrderBy()方法 – 根据指定的键按升序对序列的元素进行排序

    C#中的Linq提供了一种方便的方法来处理数据序列,其中OrderBy()是排序操作中的一个重要部分。OrderBy()方法可以按照序列中指定的键值对序列进行排序,并返回一个IEnumerable类型的序列。 语法格式 public static IOrderedEnumerable<TSource> OrderBy<TSource, TK…

    C# 2023年4月19日
    00
  • C# DateTime.AddDays()方法: 将指定的天数加到指定的日期上

    DateTime.AddDays()是C#中DateTime结构体提供的一个方法,用于将DateTime对象的日期值增加指定的天数。其方法的声明如下: public DateTime AddDays(double value); 其中value参数为需要增加的天数,可以是一个正数,也可以是一个负数。 以下是使用该方法的两个实例: 计算一个日期的前一天 假设有…

    C# 2023年4月19日
    00
  • 关于Android添加fragment后版本不兼容问题

    当在一个较低的 Android 版本中使用 fragment 时,如果没有处理好版本兼容问题,可能会导致程序崩溃或出现其他不可预知的异常。对于这种问题,我们可以采取以下措施: 1. 使用 support 包 从 Android 3.0 开始,Android 框架引入了 Fragment 和 FragmentManager 等类。然而这些类仅在 Android…

    C# 2023年6月6日
    00
  • c#使用linq把多列的List转化为只有指定列的List

    想要使用LINQ将多列的列表转化为只有指定列的列表,可以按照以下步骤进行操作: 首先创建一个包含多列数据的列表,可以使用下面的代码创建一个实例用于演示: List<Person> persons = new List<Person>() { new Person() { Id = 1, Name = "Tom", …

    C# 2023年6月1日
    00
  • asp.net 生成随机密码的具体代码

    生成随机密码是一个常见的需求,特别是在ASP.NET的网站开发中更是经常用到。本文将详细讲解ASP.NET生成随机密码的具体代码。 一. 生成指定位数的随机密码 要生成指定位数的随机密码,可以使用Random类从字符集中随机抽取指定数量的字符来进行组合。这里给出的代码生成一个8位长度的随机密码: public static string GenerateRa…

    C# 2023年5月31日
    00
  • C#连接SQL Server数据库的实例讲解

    下面是关于C#连接SQL Server数据库的完整攻略: 一、准备工作 首先需要在本地安装好SQL Server数据库,并开启相关服务。然后需要安装SqlServer.DatClient包,可以通过NuGet Package Manager搜索安装。 二、连接数据库 连接数据库的过程: using System.Data.SqlClient; namespa…

    C# 2023年6月1日
    00
合作推广
合作推广
分享本页
返回顶部