繁体   English   中英

C#验证PDF签名

[英]C# Verifying PDF signature

尝试验证PDF签名无效。 PDF由Adobe Acrobat签名,然后尝试使用客户端证书的公钥进行验证。

因此,我获得了客户端证书的公钥,对PDF进行了哈希处理,并验证了哈希值是否等于pdf签名,但是失败了。

HttpClientCertificate cert = request.ClientCertificate;
X509Certificate2 cert2 = new X509Certificate2(cert.Certificate);

PdfReader pdfreader = new PdfReader("path_to_file");

AcroFields fields = pdfreader.AcroFields;
AcroFields.Item item = fields.GetFieldItem("Signature1");
List<string> names = fields.GetSignatureNames();

foreach (string name in names){
     PdfDictionary dict = fields.GetSignatureDictionary(name);
     PdfPKCS7 pkcs7 = fields.VerifySignature(name);
     Org.BouncyCastle.X509.X509Certificate pdfSign = pkcs7.SigningCertificate;

     // Get its associated CSP and public key
     RSACryptoServiceProvider csp = (RSACryptoServiceProvider)cert2.PublicKey.Key;

     // Hash the data
     SHA256 sha256 = new SHA256Managed();

     byte[] pdfBytes = System.IO.File.ReadAllBytes("path_to_pdf");
     byte[] hash = sha256.ComputeHash(pdfBytes);

     // Verify the signature with the hash
     bool ok = csp.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA256"), pdfSing.GetSignature());
 }

首先,要验证签名是否正确,您可以简单地使用已经检索的PdfPKCS7对象,更确切地说,使用其Verify方法:

/**
 * Verify the digest.
 * @throws SignatureException on error
 * @return <CODE>true</CODE> if the signature checks out, <CODE>false</CODE> otherwise
 */
virtual public bool Verify()

因此,您可以简单地致电

bool ok = pkcs7.Verify();

oktrue只有当文件哈希签名中的散列相匹配。


关于您这样计算文档哈希的尝试

byte[] pdfBytes = System.IO.File.ReadAllBytes("path_to_pdf");
byte[] hash = sha256.ComputeHash(pdfBytes);

这确实为您提供了完整PDF的哈希值。

但是,对于具有集成签名的文档类型(例如PDF),这不是感兴趣的哈希值,因为完整的PDF显然包含集成签名!

因此,您必须在PDF中找到为签名保留的空间,并在进行哈希计算时将其忽略(参见)。 信息安全堆栈交换上的此答案 ,特别是以下图像:

集成的PDF签名如何“集成”

如果有多个签名,则您还必须考虑到,较早的签名仅对PDF的先前版本进行签名,因此仅针对文件的起始段计算哈希值,参见。 上面引用答案中的这张图片:

在此处输入链接说明

iText(Sharp)方法PdfPKCS7.Verify()将此考虑在内。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM