使用itextsharp将单独签名的哈希放置到PDF中的多个位置
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用itextsharp将单独签名的哈希放置到PDF中的多个位置相关的知识,希望对你有一定的参考价值。
我想在PDF中的多个位置放置相同的外部签名哈希(签名值)。
我已经将页面'如何放置相同的数字签名 - 多个地方在pdf-using-itextsh'中提到并尝试实现mkl提供的工作(请参阅此How to place the Same Digital signatures to Multiple places in PDF using itextsharp.net) 。
它有效。我移植它以使用web服务/ api获取外部签名的签名者字节,它也可以工作。现在由于其中一个要求,我改变了计算哈希的方式。
现在而不是(旧的):
byte[] hash = DigestAlgorithms.Digest(data, "SHA256");
byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, null, null, CryptoStandard.CMS);
我正在尝试使用(新的):
int contentEstimated=8192;
HashAlgorithm sha = new SHA256CryptoServiceProvider();
int read = 0;
byte[] buff = new byte[contentEstimated];
while ((read = data.Read(buff, 0, contentEstimated)) > 0)
{
sha.TransformBlock(buff, 0, read, buff, 0);
}
sha.TransformFinalBlock(buff, 0, 0);
byte[] hash = Org.BouncyCastle.Utilities.Encoders.Hex.Encode(sha.Hash);
string hashtext = Encoding.UTF8.GetString(hash, 0, hash.Length); //for writing it to file or sharing it to another api
byte[] hash1 = StringToByteArray(hashtext);
byte[] sh = sgn.getAuthenticatedAttributeBytes(hash1, null, null, CryptoStandard.CMS); or
byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, null, null, CryptoStandard.CMS); //tried both
如果我尝试在现有实现中使用它,签名将失效并显示错误“文档自签名后已被更改或损坏”。你能告诉我我做错了吗?
在大多数引用的页面中,他们使用这种哈希生成方法和嵌入函数,其中计算的哈希嵌入到pdf中,
byte[] paddedSig = new byte[csize];
System.Array.Copy(pk, 0, paddedSig, 0, pk.Length);
PdfDictionary dic2 = new PdfDictionary();
dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true));
appearance.Close(dic2);
谢谢。 - Tanmay
在评论中,OP澄清说他想使解决方案here使用外部签名服务,该服务接受文档哈希(更确切地说是Hex格式的文档的SHA256哈希值)并返回一个完整的CMS签名容器。
在这种情况下,原来的AllPagesSignatureContainer
方法Sign
public byte[] Sign(Stream data)
{
String hashAlgorithm = externalSignature.GetHashAlgorithm();
PdfPKCS7 sgn = new PdfPKCS7(null, chain, hashAlgorithm, false);
IDigest messageDigest = DigestUtilities.GetDigest(hashAlgorithm);
byte[] hash = DigestAlgorithms.Digest(data, hashAlgorithm);
byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, null, null, CryptoStandard.CMS);
byte[] extSignature = externalSignature.Sign(sh);
sgn.SetExternalDigest(extSignature, null, externalSignature.GetEncryptionAlgorithm());
return sgn.GetEncodedPKCS7(hash, null, null, null, CryptoStandard.CMS);
}
必须更改为不使用PdfPKCS7 sgn
创建CMS容器,而只是计算文档哈希值,将其发送到服务并使用服务返回的容器:
public byte[] Sign(Stream data)
{
String hashAlgorithm = externalSignature.GetHashAlgorithm();
IDigest messageDigest = DigestUtilities.GetDigest(hashAlgorithm);
byte[] hash = DigestAlgorithms.Digest(data, hashAlgorithm);
byte[] hexHash = Org.BouncyCastle.Utilities.Encoders.Hex.Encode(hash);
string hexHashString = Encoding.UTF8.GetString(hexHash , 0, hexHash.Length);
var response = [... call service with document hash hexHashString ...];
byte[] signatureContainer = [... extract binary CMS container from response ...];
return signatureContainer;
}
OP没有提到有关响应格式的任何内容,因此我不能多说response
部分的提取二进制CMS容器。它可以包括选择较大响应结构的一个属性,它可以包括解码编码值(可能是十六进制编码的字符串),......
以上是关于使用itextsharp将单独签名的哈希放置到PDF中的多个位置的主要内容,如果未能解决你的问题,请参考以下文章
在 C# 中使用 iTextSharp 在 PDF 中添加多个数字签名
使用 itextsharp 将图像 html 旁边的文本放置到 pdf