You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET中验证PDF双签名并提取签署人姓名?

在.NET中读取PDF签名、验证有效性并提取签署人信息的实现方案

嘿,我刚好折腾过类似的需求,针对你要验证PDF合同的两个签名、提取签署人姓名的问题,给你几个在.NET生态里可行的方案,都是亲测能用的:

1. 使用iText7(推荐,功能全面)

iText是处理PDF的老牌库,不管是加签还是验签、读取签名信息都很成熟。你需要安装几个NuGet包:

  • iText.Kernel(核心PDF处理)
  • iText.Signatures(签名相关功能)
  • BouncyCastle.Crypto(依赖的加密库,iText验签需要它)

示例代码:

using iText.Kernel.Pdf;
using iText.Signatures;
using Org.BouncyCastle.Security;
using System;
using System.Collections.Generic;

public class PdfSignatureReader
{
    public static void ReadAndValidateSignatures(string pdfPath)
    {
        // 加载PDF文档
        using var pdfReader = new PdfReader(pdfPath);
        using var pdfDocument = new PdfDocument(pdfReader);
        
        // 获取所有签名域名称
        var signatureNames = pdfDocument.GetSignatureNames();
        
        foreach (var name in signatureNames)
        {
            Console.WriteLine($"=== 签名信息: {name} ===");
            
            // 获取对应签名对象
            var signature = pdfDocument.GetSignature(name);
            
            // 1. 验证签名完整性与真实性
            var signerInfo = signature.GetSignerInfo();
            var pkcs7 = new PdfPKCS7(signerInfo.GetEncoded());
            bool isSignatureValid = pkcs7.VerifySignatureIntegrityAndAuthenticity();
            Console.WriteLine($"签名是否有效: {isSignatureValid}");
            
            // 2. 提取签署人姓名
            var signerName = pkcs7.GetSignerName();
            Console.WriteLine($"签署人姓名: {signerName}");
            
            // 可选:获取签署时间
            var signDate = pkcs7.GetSignDate().Time;
            Console.WriteLine($"签署时间: {signDate}");
        }
    }
}

如果是带时间戳的签名,iText也支持通过pkcs7.VerifyTimestamp()验证时间戳的有效性,按需扩展即可。

2. 使用PdfPig(轻量开源,适合简单场景)

PdfPig是另一个开源的PDF处理库,API更简洁,适合只需要读取签名基础信息的场景。安装NuGet包UglyToad.PdfPig即可。

示例代码:

using UglyToad.PdfPig;
using UglyToad.PdfPig.Signatures;
using System;

public class PdfPigSignatureReader
{
    public static void ExtractSignatureInfo(string pdfPath)
    {
        using var document = PdfDocument.Open(pdfPath);
        
        if (document.AcroForm?.Fields == null)
        {
            Console.WriteLine("文档无签名域");
            return;
        }
        
        foreach (var field in document.AcroForm.Fields)
        {
            if (field is SignatureField signatureField)
            {
                Console.WriteLine($"=== 签名域: {signatureField.PartialName} ===");
                
                var signatureDict = signatureField.SignatureDictionary;
                if (signatureDict == null)
                {
                    Console.WriteLine("未找到签名内容");
                    continue;
                }
                
                // 提取签署人姓名(通常存储在/Name键下)
                if (signatureDict.TryGet(NameToken.Name, out string signerName))
                {
                    Console.WriteLine($"签署人姓名: {signerName}");
                }
                
                // 如需验签,可结合BouncyCastle解析/Contents键下的签名字节
                if (signatureDict.TryGet(NameToken.Contents, out byte[] signatureBytes))
                {
                    // 这里可以用BouncyCastle解析PKCS#7格式的签名数据,实现验签逻辑
                }
            }
        }
    }
}

3. 关键注意事项

  • 签名有效性的意义:如果验证通过,说明文档在签署后未被篡改;如果失效,要么文档被修改,要么签署人的证书不被信任。
  • 证书信任链验证:生产环境中建议添加信任根证书,验证签署人证书的合法性,iText可通过pkcs7.VerifyCertificateChain()实现。
  • 兼容多种签名类型:不管是Adobe标准的PKCS#7签名还是PAdES签名,上述库都能原生支持,无需额外适配。

内容的提问来源于stack exchange,提问作者Paulo Vaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:12:33