C# 给PDF签名时添加时间戳的2种方法(附VB.NET代码)
在PDF添加签名时,支持添加可信时间戳来保证文档的法律效应。本文,将通过C#程序代码介绍如何添加可信时间戳,可通过2种方法来实现。文中附上VB.NET代码,有需可供参考。
一、程序运行环境
- 编译环境:Visual Studio/.NetFramework 4.8
- 所需测试文件:PDF、.pfx数字证书及秘钥、PDF类库(spire.pdf.dll 7.5.7)
- 可信时间戳服务器:URL地址
注:VS程序中,在“解决方案资源管理器中”先引用spire.pdf.dll文件,如下图,

这里可以通过Nuget下载该文件。或者在手动下载引用,dll文件在下载后的文件包BIN文件夹下,如本次测试使用的是.NET4.0下面的dll,即spire.pdf_7.5.7\BIN\NET4.0\Spire.Pdf.dll,如图:

二、程序代码
添加签名时,这里可分别通过两个类来实现,即PdfSignature 和 PdfOrdinarySignatureMaker类。下面分别以两个代码示例展示如何签名并添加时间戳。
1. 通过PdfSignature类来签名,添加时间戳
C#
using Spire.Pdf;
using Spire.Pdf.Security;
using System.Drawing; namespace TimeStamp
{
class Program
{
static void Main(string[] args)
{
//加载PDF文档
PdfDocument pdf = new PdfDocument();
pdf.LoadFromFile("sample.pdf"); //获取第2页
PdfPageBase page = pdf.Pages[1]; //加载数字证书(.pfx文件及秘钥)
PdfCertificate cert = new PdfCertificate("test.pfx", "123456"); //加载签名图片
Spire.Pdf.Graphics.PdfImage image = Spire.Pdf.Graphics.PdfImage.FromFile("sign.png"); //添加与图片大小相同的签名到第2页指定坐标位置
PdfSignature signature = new PdfSignature(page.Document, page, cert, "sign1");//添加数字签名
signature.Bounds = new RectangleF(new PointF(400,700), new SizeF(image.Width, image.Height));//设置签名的页面坐标位置、大小与图片相同
signature.SignImageSource = image;
signature.GraphicsMode = Spire.Pdf.Security.GraphicMode.SignImageAndSignDetail;//设置签名为图片模式
signature.SignImageLayout = Spire.Pdf.Security.SignImageLayout.Stretch;
signature.DocumentPermissions = Spire.Pdf.Security.PdfCertificationFlags.AllowFormFill | Spire.Pdf.Security.PdfCertificationFlags.AllowComments;//文档权限 //配置时间戳服务器,添加时间戳
string url = "Your TimeStamp Server URL";
signature.ConfigureTimestamp(url);
//signature.ConfigureTimestamp(url, "Author", "123654");//添加时间戳时设置用户名和密码 //保存文档
pdf.SaveToFile("TimeStamp1.pdf",FileFormat.PDF);
System.Diagnostics.Process.Start("TimeStamp1.pdf");
}
}
}
VB.NET
Imports Spire.Pdf
Imports Spire.Pdf.Security
Imports System.Drawing Namespace TimeStamp
Class Program
Private Shared Sub Main(args As String())
'加载PDF文档
Dim pdf As New PdfDocument()
pdf.LoadFromFile("sample.pdf") '获取第2页
Dim page As PdfPageBase = pdf.Pages(1) '加载数字证书(.pfx文件及秘钥)
Dim cert As New PdfCertificate("test.pfx", "123456") '加载签名图片
Dim image As Spire.Pdf.Graphics.PdfImage = Spire.Pdf.Graphics.PdfImage.FromFile("sign.png") '添加与图片大小相同的签名到第2页指定坐标位置
Dim signature As New PdfSignature(page.Document, page, cert, "sign1") '添加数字签名
signature.Bounds = New RectangleF(New PointF(400, 700), New SizeF(image.Width, image.Height)) '设置签名的页面坐标位置、大小与图片相同
signature.SignImageSource = image
signature.GraphicsMode = Spire.Pdf.Security.GraphicMode.SignImageAndSignDetail '设置签名为图片模式
signature.SignImageLayout = Spire.Pdf.Security.SignImageLayout.Stretch
signature.DocumentPermissions = Spire.Pdf.Security.PdfCertificationFlags.AllowFormFill Or Spire.Pdf.Security.PdfCertificationFlags.AllowComments'文档权限 '配置时间戳服务器,添加时间戳
Dim url As String = "Your TimeStamp Server URL"
signature.ConfigureTimestamp(url)
'signature.ConfigureTimestamp(url, "Author", "123654");//添加时间戳时设置用户名和密码 '保存文档
pdf.SaveToFile("TimeStamp1.pdf", FileFormat.PDF)
System.Diagnostics.Process.Start("TimeStamp1.pdf")
End Sub
End Class
End Namespace
签名时间戳添加结果:

2. 通过PdfOrdinarySignatureMaker类来签名,添加时间戳
C#
using Spire.Pdf;
using Spire.Pdf.Graphics;
using Spire.Pdf.Interactive.DigitalSignatures;
using System.Drawing;
using System.Security.Cryptography.X509Certificates; namespace TimeStamp2
{
class Program
{
static void Main(string[] args)
{
//加载PDF文档
PdfDocument doc = new PdfDocument();
doc.LoadFromFile("sample.pdf"); //加载pfx数字证书及秘钥
X509Certificate2 x509 = new X509Certificate2("test.pfx", "123456"); //实例化PdfPKCS7Formatter类的对象
PdfPKCS7Formatter formatter = new PdfPKCS7Formatter(x509, false);
formatter.TimestampService = new TSAHttpService("Your TimeStamp Server URL");//配置时间戳服务器 //添加签名
PdfOrdinarySignatureMaker signatureMaker = new PdfOrdinarySignatureMaker(doc, formatter);
IPdfSignatureAppearance signatureAppearance = new PdfCustomSignatureAppearance();
signatureMaker.MakeSignature("sign", doc.Pages[1], 400, 650, 150, 80, signatureAppearance); //保存签名后的PDF文档
doc.SaveToFile("TimeStamp2.pdf", FileFormat.PDF);
System.Diagnostics.Process.Start("TimeStamp2.pdf"); }
public class PdfCustomSignatureAppearance : IPdfSignatureAppearance
{
public void Generate(PdfCanvas canvas)
{
PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("Arial", 12), true);
canvas.DrawString("SIGNED! A CLASS.\n By Tom Smith", font, PdfBrushes.Red, new PointF(0, 0));
}
}
}
}
VB.NET
Imports Spire.Pdf
Imports Spire.Pdf.Graphics
Imports Spire.Pdf.Interactive.DigitalSignatures
Imports System.Drawing
Imports System.Security.Cryptography.X509Certificates Namespace TimeStamp2
Class Program
Private Shared Sub Main(args As String())
'加载PDF文档
Dim doc As New PdfDocument()
doc.LoadFromFile("sample.pdf") '加载pfx数字证书及秘钥
Dim x509 As New X509Certificate2("test.pfx", "123456") '实例化PdfPKCS7Formatter类的对象
Dim formatter As New PdfPKCS7Formatter(x509, False)
formatter.TimestampService = New TSAHttpService("Your TimeStamp Server URL")
'配置时间戳服务器 '添加签名
Dim signatureMaker As New PdfOrdinarySignatureMaker(doc, formatter)
Dim signatureAppearance As IPdfSignatureAppearance = New PdfCustomSignatureAppearance()
signatureMaker.MakeSignature("sign", doc.Pages(1), 400, 650, 150, 80, _
signatureAppearance) '保存签名后的PDF文档
doc.SaveToFile("TimeStamp2.pdf", FileFormat.PDF)
System.Diagnostics.Process.Start("TimeStamp2.pdf") End Sub
Public Class PdfCustomSignatureAppearance
Implements IPdfSignatureAppearance
Public Sub Generate(canvas As PdfCanvas)
Dim font As New PdfTrueTypeFont(New Font("Arial", 12), True)
canvas.DrawString("SIGNED! A CLASS." & vbLf & " By Tom Smith", font, PdfBrushes.Red, New PointF(0, 0))
End Sub
End Class
End Class
End Namespace
签名时间戳添加结果:

以上是本文关于如何在C#程序中给PDF签名添加时间戳的方法。
内容原创,如需转载请务必注明出处!
C# 给PDF签名时添加时间戳的2种方法(附VB.NET代码)的更多相关文章
- Java 给PDF签名时添加可信时间戳
一.程序运行环境 编译环境:IntelliJ IDEA 所需测试文件:PDF..pfx数字证书及密钥.PDF Jar包(Free Spire.PDF for Java).签名图片(.png格式) 可信 ...
- Linux添加系统调用的两种方法
前言 系统调用的基本原理 系统调用其实就是函数调用,只不过调用的是内核态的函数,但是我们知道,用户态是不能随意调用内核态的函数的,所以采用软中断的方式从用户态陷入到内核态.在内核中通过软中断0X80, ...
- Apache shiro集群实现 (八) web集群时session同步的3种方法
Apache shiro集群实现 (一) shiro入门介绍 Apache shiro集群实现 (二) shiro 的INI配置 Apache shiro集群实现 (三)shiro身份认证(Shiro ...
- 给Repeater控件里添加序号的5种方法
Repeater是我们经常用的一个显示数据集的数据控件,经常我们希望在数据前显示数据的序号,那么我们该怎么为Repeater控件添加序号呢?下面编辑为大家介绍几种常用的为Repeater控件添加序号的 ...
- mysql 中添加索引的三种方法
原文:http://www.andyqian.com/2016/04/06/database/mysqleindex/ 在mysql中有多种索引,有普通索引,全文索引,唯一索引,多列索引,小伙伴们可以 ...
- delphi TreeView 从数据库添加节点的四种方法
方法一:delphi中递归算法构建treeView 过程:通过读取数据库中table1的数据,来构建一颗树.table1有两个字段:ID,preID,即当前结点标志和父结点标志.所以整个树的表示为父母 ...
- Cocos Creator 为Button添加事件的两种方法
Button添加事件 Button 目前只支持 Click 事件,即当用户点击并释放 Button 时才会触发相应的回调函数.通过脚本代码添加回调方法一这种方法添加的事件回调和使用编辑器添加的事件回调 ...
- 【转】web集群时session同步的3种方法
转载请注明作者:海底苍鹰地址:http://blog.51yip.com/server/922.html 在做了web集群后,你肯定会首先考虑session同步问题,因为通过负载均衡后,同一个IP访问 ...
- web集群时session同步的3种方法[转]
在做了web集群后,你肯定会首先考虑session同步问题,因为通过负载均衡后,同一个IP访问同一个页面会被分配到不同的服务器上,如果session不同步的话,一个登录用户,一会是登录状态,一会又不是 ...
随机推荐
- 走进docker-swarm 带大家快速掌握docker自带编排工具
什么是Docker Swarm? 对比Docker 前面我们介绍过Docker可以理解成是一个我们的服务的独立运行的容器,那么在实际工作中,我们的系统可能是一个微服务应用,系统中根据业务拆分成多个模块 ...
- flexbox(弹性盒布局模型),以及适用场景
一.是什么 Flexible Box 简称 flex,意为"弹性布局",可以简便.完整.响应式地实现各种页面布局 采用Flex布局的元素,称为flex容器container 它的所 ...
- mvel 配合正则表达式实现文本替换
mvel 依赖 <dependency> <groupId>org.mvel</groupId> <artifactId>mvel2</artif ...
- OOJML系列总结
目录 0x0 JML理论相关 0.0 概念及作用 0.1 JML语法学习 0x1 使用openJml以及JMLUnitNG 1.0 使用openjml 1.1使用JMLUnitNG 0x2 作业架构设 ...
- (十一)VMware Harbor 配置管理
VMware Harbor 配置管理 这篇主要学习一下,项目下的配置管理. 主要功能就是修改项目的访问权限 当将访问权限改为
- (二十)VMware Harbor - API
可以用swagger在线解析 http://editor.swagger.io/将swagger.yaml中的内容拷贝到里面即可. 官方文档说明链接如下:https://github.com/vmwa ...
- 利用Apache部署静态网站(一)
Apache是世界使用排名第一的Web服务器软件.它可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是最流行的Web服务器端软件之一.它快速.可靠并且可通过简单的API扩充, ...
- 按照自己的思路去研究Spring AOP源码【1】
目录 一个例子 Spring AOP 原理 从@EnableAspectJAutoProxy注解入手 什么时候会创建代理对象? 方法执行时怎么实现拦截的? 总结 问题 参考 一个例子 // 定义一个切 ...
- 基于vite2+electron12后台管理模板|Electron后台框架系统
前一溜时间有给大家分享一个 electron+vite跨端短视频 项目.这次分享的是vite2.x和electron实现跨平台后台框架,支持国际化多语言配置.导航菜单+树形菜单两种路由菜单模式.展开/ ...
- php swoole 和 websocket的初次碰撞
php swoole 扩展仿佛为php开发打开了一扇窗户 阅读文档 https://wiki.swoole.com php workman和swoole原来是两个东东 swoole的使用范围更广,能做 ...