【发布时间】:2020-12-16 15:11:39
【问题描述】:
目标是实现一个 PDF 签名过程,其中服务器根据请求向客户端提供要签名的哈希值。然后,客户端使用通过 PKCS#11 接口从智能卡获得的私钥对给定的散列进行签名。然后将签名发送回服务器,以便使用 iTextSharp 5.5.4 附加到 PDF 文件中。
在 Acrobat Reader 中查看签名时,它给了我错误“自应用签名后文档已被更改或损坏”。
这是我在服务器上计算哈希的方法。
public byte[] GetHashToSign(byte[] unsignedPdfBytes, out string signatureFieldName, out byte[] tempFile)
{
byte[] result = null;
using (PdfReader reader = new PdfReader(unsignedPdfBytes))
{
using (MemoryStream stream = new MemoryStream())
{
IExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ETSI_CADES_DETACHED);
PdfStamper stamper = PdfStamper.CreateSignature(reader, stream, '\0');
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
signatureFieldName = appearance.FieldName;
MakeSignature.SignExternalContainer(appearance, external, 30000);
result = SHA256Managed.Create().ComputeHash(appearance.GetRangeStream());
tempFile = stream.ToArray();
}
return result;
}
}
在客户端对给定的哈希签名后,我将签名的哈希嵌入到服务器上的 pdf 中。这是我用来嵌入签名哈希的方法。
public void EmbedSignature(byte[] tempPdfBytes, string signatureFieldName, byte[] signedBytes, string signedPdfPath)
{
using (PdfReader pdfReader = new PdfReader(tempPdfBytes))
{
using (FileStream os = File.OpenWrite(signedPdfPath))
{
IExternalSignatureContainer external = new MyExternalSignatureContainer(signedBytes);
MakeSignature.SignDeferred(pdfReader, signatureFieldName, os, external);
}
}
}
另一方面,当我使用 SHA-1 时,我没有收到任何错误。 Acrobat Reader 验证签名如下。但我必须使用 SHA256。
这是我在服务器上使用 SHA-1 计算哈希的方法。
public byte[] GetHashToSign(byte[] unsignedPdfBytes, out string signatureFieldName, out byte[] tempFile)
{
byte[] result = null;
using (PdfReader reader = new PdfReader(unsignedPdfBytes))
{
using (MemoryStream stream = new MemoryStream())
{
IExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_SHA1);
PdfStamper stamper = PdfStamper.CreateSignature(reader, stream, '\0');
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
signatureFieldName = appearance.FieldName;
MakeSignature.SignExternalContainer(appearance, external, 30000);
result = SHA1Managed.Create().ComputeHash(appearance.GetRangeStream());
tempFile = stream.ToArray();
}
return result;
}
}
编辑:Signed PDF - Invalid signature with SHA256
Signed PDF - valid signature with SHA1
我研究了所有相关条目,但没有得到任何结果来处理这个问题。 我错过了什么或做错了什么?
【问题讨论】:
-
请分享一个由您的代码签名的示例 PDF 以分析问题。
-
一个问题,但是:你说 “然后客户端使用通过 PKCS#11 接口从智能卡获得的私钥对给定的哈希进行签名。” - 有这个代码也被改编为处理 SHA256 哈希而不是 SHA1 哈希?
-
感谢您的回答,我添加了签名的 pdf。
-
我使用 SHA 256 算法通过 PKCS#11 接口使用智能卡进行签名。
-
感谢您的文件。我应该在代码中看到问题,但分析文件最终让它们跃入我的视线。我会写一个答案。
标签: c# pdf itext digital-signature