简体   繁体   English

C#验证PDF签名

[英]C# Verifying PDF signature

Trying to validate PDF signature isn't working. 尝试验证PDF签名无效。 The PDF were signed by Adobe Acrobat and then trying to verify it with the public key of the client certificate. PDF由Adobe Acrobat签名,然后尝试使用客户端证书的公钥进行验证。

So I get the public key of the client certificate, hash the PDF and verify if the hash is equal to the pdf signature, but it fails. 因此,我获得了客户端证书的公钥,对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());
 }

First, to verify whether the signature correctly you can simply use the PdfPKCS7 object you already retrieved, more exactly its Verify method: 首先,要验证签名是否正确,您可以简单地使用已经检索的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()

Thus, you can simply call 因此,您可以简单地致电

bool ok = pkcs7.Verify();

and ok is true only if the document hash matches the hash in the signature. oktrue只有当文件哈希签名中的散列相匹配。


Concerning your attempt to calculate the document hash like this 关于您这样计算文档哈希的尝试

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

This indeed gives you the hash value of the complete PDF . 这确实为您提供了完整PDF的哈希值。

For document types with integrated signatures like PDFs, though, this is not the hash of interest because the complete PDF obviously includes the integrated signature! 但是,对于具有集成签名的文档类型(例如PDF),这不是感兴趣的哈希值,因为完整的PDF显然包含集成签名!

Thus, you have to find the space reserved for the signature in the PDF and ignore it during hash calculation, cf. 因此,您必须在PDF中找到为签名保留的空间,并在进行哈希计算时将其忽略(参见)。 this answer on Information Security Stack Exchange, in particular this image: 信息安全堆栈交换上的此答案 ,特别是以下图像:

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

In case of multiple signatures you furthermore have to consider that the earlier signatures only sign a former revision of the PDF, so the hash is to be calculated only for a starting segment of the file, cf. 如果有多个签名,则您还必须考虑到,较早的签名仅对PDF的先前版本进行签名,因此仅针对文件的起始段计算哈希值,参见。 this image from the answer referenced above : 上面引用答案中的这张图片:

在此处输入链接说明

The iText(Sharp) method PdfPKCS7.Verify() takes all this into account. iText(Sharp)方法PdfPKCS7.Verify()将此考虑在内。

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

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