Spire.PDFfor.NET是一款专业的基于.NET平台的PDF文档控制组件。它能够让开发人员在不使用AdobeAcrobat和其他外部控件的情况下,运用.NET应用程序创建,阅读,编写和操纵PDF文档。本文将利用其实现添加数字签名,需要的可以参考一下
背景
- 对PDF文档进行数字签名的需求
- 对PDF文档添加水印的需求
- 网上资料版本不一或不全
本文章提到的Spire.Pdf均是使用的Spire.Pdf for .NET,除此之前还有其他语言的版本,如Spire.Pdf for JAVA;
Spire.Pdf主要用于操作PDF,另外还有Spire.Excel、Spire.Doc等
主要介绍了在C#中使用Spire.Pdf组件包对PDF文档进行数字签名、添加水印功能,旨在引导大家快速、轻松的对PDF文档进行数字签名和添加水印功能;
简介
Spire.PDF for .NET 是一款专业的基于.NET平台的PDF文档控制组件。它能够让开发人员在不使用Adobe Acrobat和其他外部控件的情况下,运用.NET 应用程序创建,阅读,编写和操纵PDF 文档。Spire.PDF for .NET 功能丰富,除了基本的功能比如:绘制多种图形,图片,创建窗体字段,插入页眉页脚,输入数据表,自动对大型表格进行分页外,Spire.PDF for .NET还支持PDF数字签名,将HTML转换成PDF格式,提取PDF文档中的文本信息和图片等,目前Spire.PDF for .NET共有两个版本,一个是免费版本一个是付费版本,免费版本如果只是处理简单的pdf是没问题的,但是如果涉及到输出为pdf则会只显示前10页,第十一页则是预定的购买页介绍,我这里主要是对PDF文档的数字签名和水印,所以不涉及输出pdf;
依赖
本文示例代码依赖于Spire.Pdf,可以在项目中使用NuGet程序包引入。
源码
核心代码
public class DigitalSignature
{
/// <summary>
/// 页顶部红色警告字样覆盖白色图片Base64.
/// </summary>
private const string WatermarkCoverBase64 = "/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCABHAycDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9U6KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z";
/// <summary>
/// 构造函数.
/// </summary>
/// <param name="waitSignFile">待签名文件.</param>
/// <param name="imageSign">签名图片.</param>
/// <param name="pfx">签名证书.</param>
/// <param name="pfxPwd">签名证书密码.</param>
public DigitalSignature(byte[] waitSignFile, byte[] imageSign, byte[] pfx, string pfxPwd)
{
this.WaitSignFile = waitSignFile;
this.ImageSign = imageSign;
this.Pfx = pfx;
this.PfxPwd = pfxPwd;
}
/// <summary>
/// 构造函数.
/// </summary>
/// <param name="waitSignFile">待签名文件.</param>
/// <param name="charactersSign">签名文字.</param>
/// <param name="signRightLeftWidth">签名右向左宽度.</param>
/// <param name="signBottomUpHeight">签名低向上高度.</param>
/// <param name="pfx">签名证书.</param>
/// <param name="pfxPwd">签名证书密码.</param>
public DigitalSignature(byte[] waitSignFile, string charactersSign, float signRightLeftWidth, float signBottomUpHeight, byte[] pfx, string pfxPwd)
{
this.WaitSignFile = waitSignFile;
this.CharactersSign = charactersSign;
this.SignRightLeftWidth = signRightLeftWidth;
this.SignBottomUpHeight = signBottomUpHeight;
this.Pfx = pfx;
this.PfxPwd = pfxPwd;
}
/// <summary>
/// 构造函数.
/// </summary>
/// <param name="waitSignFile">待签名文件.</param>
/// <param name="imageSign">签名图片.</param>
/// <param name="charactersSign">签名文字.</param>
/// <param name="pfx">签名证书.</param>
/// <param name="pfxPwd">签名证书密码.</param>
public DigitalSignature(byte[] waitSignFile, byte[] imageSign, string charactersSign, byte[] pfx, string pfxPwd)
{
this.WaitSignFile = waitSignFile;
this.ImageSign = imageSign;
this.CharactersSign = charactersSign;
this.Pfx = pfx;
this.PfxPwd = pfxPwd;
}
/// <summary>
/// Gets or sets 待签名文件.
/// </summary>
public byte[] WaitSignFile { get; set; }
/// <summary>
/// Gets or sets 图签名.
/// </summary>
public byte[] ImageSign { get; set; }
/// <summary>
/// Gets or sets 文字签名.
/// </summary>
public string CharactersSign { get; set; }
/// <summary>
/// Gets or sets 签名右向左的宽度.
/// </summary>
public float? SignRightLeftWidth { get; set; }
/// <summary>
/// Gets or sets 签名顶向上高度.
/// </summary>
public float? SignBottomUpHeight { get; set; }
/// <summary>
/// Gets or sets 签名索引页面(不指定默认所有页进行签名).
/// </summary>
public int? SignIndexPages { get; set; }
/// <summary>
/// Gets or sets Pfx证书.
/// </summary>
public byte[] Pfx { get; set; }
/// <summary>
/// Gets or sets Pfx证书密码.
/// </summary>
public string PfxPwd { get; set; }
public Stream Signature()
{
///加载PDF文档
PdfDocument pdf = new PdfDocument();
pdf.LoadFromBytes(this.WaitSignFile);
if (pdf?.Pages?.Count <= 0)
{
throw new Exception("文件有误");
}
X509Certificate2 x509 = new X509Certificate2(this.Pfx, this.PfxPwd);
PdfOrdinarySignatureMaker signatureMaker = new PdfOrdinarySignatureMaker(pdf, x509);
var appearance = new PdfCustomSignatureAppearance(this.CharactersSign, this.ImageSign, this.SignRightLeftWidth, this.SignBottomUpHeight);
IPdfSignatureAppearance signatureAppearance = appearance;
// 绘画白底图片
PdfRubberStampAnnotation logoStamp = new PdfRubberStampAnnotation(new RectangleF(new PointF(0, 0), new SizeF(350, 22)));
PdfAppearance logoApprearance = new PdfAppearance(logoStamp);
//var logoPath = AppDomain.CurrentDomain.BaseDirectory + "\\white.jpg";
byte[] byt = Convert.FromBase64String(WatermarkCoverBase64);
Stream streamByLogo = new MemoryStream(byt);
PdfImage image = PdfImage.FromStream(streamByLogo);
PdfTemplate template = new PdfTemplate(350, 22);
template.Graphics.DrawImage(image, 0, 0);
logoApprearance.Normal = template;
logoStamp.Appearance = logoApprearance;
if (this.SignIndexPages.HasValue)
{
if (this.SignIndexPages.Value < 0 || this.SignIndexPages.Value > pdf?.Pages?.Count)
{
throw new Exception("签名索引页有误");
}
var page = pdf.Pages[this.SignIndexPages.Value];
// 添加白底图片覆盖页面顶部印记
page.AnnotationsWidget.Add(logoStamp);
// 在页面中的指定位置添加可视化签名
signatureMaker.MakeSignature("signName_", page, page.ActualSize.Width - appearance.SignRightLeftWidth, page.ActualSize.Height - appearance.SignBottomUpHeight, appearance.SignRightLeftWidth, appearance.SignBottomUpHeight, signatureAppearance);
}
else
{
foreach (PdfPageBase page in pdf.Pages)
{
// 添加白底图片覆盖页面顶部印记
page.AnnotationsWidget.Add(logoStamp);
// 在页面中的指定位置添加可视化签名
signatureMaker.MakeSignature("signName_", page, page.ActualSize.Width - appearance.SignRightLeftWidth, page.ActualSize.Height - appearance.SignBottomUpHeight, appearance.SignRightLeftWidth, appearance.SignBottomUpHeight, signatureAppearance);
}
}
MemoryStream stream = new MemoryStream();
pdf.SaveToStream(stream, FileFormat.PDF);
pdf.Close();
return stream;
}
/// <summary>
/// 使用第三方插件 =》 去除 Evaluation Warning : The document was created with Spire.PDF for .NET.
/// </summary>
/// <param name="sourcePdfs">原文件地址</param>
//private static MemoryStream ClearPdfFilesFirstPage(MemoryStream sourcePdf)
//{
// iTextSharp.text.pdf.PdfReader reader = null;
// iTextSharp.text.Document document = new iTextSharp.text.Document();
// iTextSharp.text.pdf.PdfImportedPage page = null;
// iTextSharp.text.pdf.PdfCopy pdfCpy = null;
// int n = 0;
// reader = new iTextSharp.text.pdf.PdfReader(sourcePdf);
// reader.ConsolidateNamedDestinations();
// n = reader.NumberOfPages;
// document = new iTextSharp.text.Document(reader.GetPageSizeWithRotation(1));
// MemoryStream memoryStream = new MemoryStream();
// pdfCpy = new iTextSharp.text.pdf.PdfCopy(document, memoryStream);
// document.Open();
// for (int j = 2; j <= n; j++)
// {
// page = pdfCpy.GetImportedPage(reader, j);
// pdfCpy.AddPage(page);
// }
// reader.Close();
// document.Close();
// return memoryStream;
/
本文标题为:C#利用Spire.Pdf包实现为PDF添加数字签名
基础教程推荐
- C#控制台实现飞行棋小游戏 2023-04-22
- C# List实现行转列的通用方案 2022-11-02
- ZooKeeper的安装及部署教程 2023-01-22
- C#类和结构详解 2023-05-30
- C# windows语音识别与朗读实例 2023-04-27
- 一个读写csv文件的C#类 2022-11-06
- unity实现动态排行榜 2023-04-27
- winform把Office转成PDF文件 2023-06-14
- C# 调用WebService的方法 2023-03-09
- linux – 如何在Debian Jessie中安装dotnet core sdk 2023-09-26