C#验证PDF签名 [英] C# Verifying PDF signature

查看:124
本文介绍了C#验证PDF签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



所以我得到了客户端证书的公钥,对PDF,并验证哈希是否等于pdf签名,但失败。

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

PdfReader pdfreader = new PdfReader( path_to_file);

AcroFields字段= pdfreader.AcroFields;
AcroFields.Item item = fields.GetFieldItem( Signature1);
List< string>名称= fields.GetSignatureNames();

foreach(名称中的字符串名称){
PdfDictionary dict = fields.GetSignatureDictionary(name);
PdfPKCS7 pkcs7 = fields.VerifySignature(name);
Org.BouncyCastle.X509.X509Certificate pdfSign = pkcs7.SigningCertificate;

//获取其关联的CSP和公钥
RSACryptoServiceProvider csp =(RSACryptoServiceProvider)cert2.PublicKey.Key;

//散列数据
SHA256 sha256 = new SHA256Managed();

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

//用哈希值
验证签名bool ok = csp.VerifyHash(hash,CryptoConfig.MapNameToOID( SHA256),pdfSing.GetSignature());
}


解决方案

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

  / ** 
*验证摘要。
* @错误时抛出SignatureException
* @return< CODE> true< / CODE>如果签名签出,则< CODE> false< / CODE>否则
* /
虚拟公共布尔Verify()

因此,您可以只需调用

  bool ok = pkcs7.Verify(); 

并且 ok true 仅当文档哈希与签名中的哈希匹配时。






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

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

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



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



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



< img src = https://i.stack.imgur.com/GKdYw.jpg alt =在此处输入链接描述>



iText(Sharp)方法 PdfPKCS7.Verify()将所有这些考虑在内。


Trying to validate PDF signature isn't working. The PDF were signed by Adobe Acrobat and then trying to verify it with the public key of the client certificate.

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.

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:

/**
 * 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.


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.

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!

Thus, you have to find the space reserved for the signature in the PDF and ignore it during hash calculation, cf. this answer on Information Security Stack Exchange, in particular this image:

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. this image from the answer referenced above:

The iText(Sharp) method PdfPKCS7.Verify() takes all this into account.

这篇关于C#验证PDF签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆