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不同步的话,一个登录用户,一会是登录状态,一会又不是 ...
随机推荐
- 软件漏洞--Hello-Shellcode
软件漏洞--Hello-Shellcode 使用上一次的栈溢出的漏洞软件 可以直接通过栈溢出来修改返回值,或者要跳转的函数地址 实现一个ShellCode来跳转自己的代码 源bug软件代码 #defi ...
- SpringBoot中整合Redis、Ehcache使用配置切换 并且整合到Shiro中
在SpringBoot中Shiro缓存使用Redis.Ehcache实现的两种方式实例 SpringBoot 中配置redis作为session 缓存器. 让shiro引用 本文是建立在你是使用这sh ...
- go中semaphore(信号量)源码解读
运行时信号量机制 semaphore 前言 作用是什么 几个主要的方法 如何实现 sudog 缓存 acquireSudog releaseSudog semaphore poll_runtime_S ...
- kubernetes使用statefulset部署mongoDB 单机版 自定义配置文件、密码等
注: 官方镜像地址: https://hub.docker.com/_/mongo?tab=description docker版的mongo移除了默认的/etc/mongo.conf, 修改了db数 ...
- 经典变长指令SIB
前言 ModR/M字段是用来进行内存寻址的,可当地址形如DS:[EAX + ECX*2 + 12345678]时,仅仅靠ModR/M字段,是描述不出来的. 这时就在ModR/M后面增加一个SIB字节, ...
- 以Aliyun体验机为例,从零搭建LNMPR环境(下)
使用云服务器搭建 Web 运行环境,尤其是搭建常见的 LNMPR(Linux+Nginx+MySQL+PHP+Redis) 环境,对于开发人员是必备的职场基本技能之一.在这里,借着搭建我的" ...
- 2020北航OO第三单元总结
2020北航OO第三单元总结 本单元要求是根据JML规格完善代码,初看是一个简单的代码照搬实现的东西,但最后才发现由于CPU时间的限制,还考察了大量优化策略及数据结构中关于图的知识,是一次非常注重细节 ...
- 基于MATLAB的手写公式识别(1)
基于MATLAB的手写公式识别 reason:课程要求以及对MATLAB强大生命力的探索欲望: plan date:2021/3/28-2021/4/12 plan: 进行材料搜集和思路整理: 在已知 ...
- jsp JDBC连接MySQL数据库操作标准流程参考
1. 此案例以帐号密码后台更新维护为例子,对数据库调取数据更新流程进行演示: 代码示例: <%@page import="java.io.IOException"%> ...
- UVA11300分金币
题意: 圆桌旁作者n个人,每个人都有一定数量的金币,他们每次可以给相邻的人一枚金币(可以给多次),问所有人金币数都相同的话最少要给多少次金币.思路: 这个题目感觉很好,首先我们可 ...