我正在开发WebService,客户可以签署PDF,这是以下步骤:
我在尝试将签名哈希插入/更新到pdf时遇到了一个大问题。
我正在使用iTextSharp。
我已经阅读了白皮书" PDF文档的数字签名"来自Bruno Lowagie,这是一个很好的帮助,但我无法弄清楚如何插入签名的哈希,顺便说一下,这是我唯一拥有的,没有证书,没有任何东西。
请帮助。
加布里埃尔
答案 0 :(得分:1)
根据您的评论,您目前的方法如下:
基本上我像这样提取pdf文件的哈希值。
private string FileHash(byte[] vGblFilePDF) { using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider()) { vGblHash = Convert.ToBase64String(sha1.ComputeHash(vGblFilePDF)); } return vGblHash; }
然后我将它发送给提供商提供WS,只添加一个Id号码,然后提供商发回给我(在识别之后)签名的哈希值,我必须插入到pdf中。
这种做法从根本上说是错误的,你已经开始计算错误的哈希了!
首先必须准备PDF ;在此准备步骤中,您将某些结构添加到PDF中,将PDF标记为包含签名,并为稍后插入签名容器保留一个部分;除了保留的部分之外的所有都要进行哈希处理:
(有关其他文献的背景和指示,参见this answer。)
此后,必须创建一个包含该文档哈希签名的完整PKCS#7 / CMS签名容器并将其插入该保留部分。
这就是大多数iText签名代码(此处为Java)为您所做的事情:
PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
// Creating the appearance
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setReason(reason);
appearance.setLocation(location);
appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");
// Creating the signature
ExternalDigest digest = new BouncyCastleDigest();
ExternalSignature signature = ...;
MakeSignature.signDetached(appearance, digest, signature, chain, null, null, null, 0, subfilter);
(取自C2_01_SignHelloWorld.java相当于C2_01_SignHelloWorld.cs)
您只需要提供与您的提供商沟通的ExternalSignature
/ IExternalSignature
实施:
public interface IExternalSignature {
/**
* Returns the hash algorithm.
* @return the hash algorithm (e.g. "SHA-1", "SHA-256,...")
*/
String GetHashAlgorithm();
/**
* Returns the encryption algorithm used for signing.
* @return the encryption algorithm ("RSA" or "DSA")
*/
String GetEncryptionAlgorithm();
/**
* Signs it using the encryption algorithm in combination with
* the digest algorithm.
* @param message the message you want to be hashed and signed
* @return a signed message digest
* @throws GeneralSecurityException
*/
byte[] Sign(byte[] message);
}