我正在开发一个客户端 - 服务器应用程序,客户端必须使用签名对PDF文档进行签名并将其上载到服务器.任务由一个事实,即客户不必嵌入签名转换成PDF的手段,他们只能读取原始字节和原始字节的形式生成签名复杂.
我正在尝试实现以下工作流程:
我发现了一些提取字节的代码示例,用于签名并将签名字节嵌入到PDF中(这是我正在使用的主要示例).
问题是这个示例执行一个程序中的所有步骤,它在获取文档哈希后立即嵌入签名而不关闭PdfStamper.我需要一些方法来保存文档添加签名域和获取后sha.Hash,然后在一段时间后(当服务器收到计算签名)打开文档,并嵌入签名值到PDF.
您能否提供一个方法来修改这个代码,以便在步骤(2)和(4)可以是独立的,并且不需要共享实例PdfReader和PdfStamper?
自己搞清楚了.这段代码向我指出了正确的方向.
原来服务器上的进程必须如下:
相关的服务器代码:
public static byte[] GetBytesToSign(string unsignedPdf, string tempPdf, string signatureFieldName)
{
using (PdfReader reader = new PdfReader(unsignedPdf))
{
using (FileStream os = File.OpenWrite(tempPdf))
{
PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0');
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
appearance.SetVisibleSignature(new Rectangle(36, 748, 144, 780), 1, signatureFieldName);
IExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKMS, PdfName.ADBE_PKCS7_SHA1);
MakeSignature.SignExternalContainer(appearance, external, 8192);
return SHA1Managed.Create().ComputeHash(appearance.GetRangeStream());
}
}
}
public static void EmbedSignature(string tempPdf, string signedPdf, string signatureFieldName, byte[] signedBytes)
{
using (PdfReader reader = new PdfReader(tempPdf))
{
using (FileStream os = File.OpenWrite(signedPdf))
{
IExternalSignatureContainer external = new MyExternalSignatureContainer(signedBytes);
MakeSignature.SignDeferred(reader, signatureFieldName, os, external);
}
}
}
private class MyExternalSignatureContainer : IExternalSignatureContainer
{
private readonly byte[] signedBytes;
public MyExternalSignatureContainer(byte[] signedBytes)
{
this.signedBytes = signedBytes;
}
public byte[] Sign(Stream data)
{
return signedBytes;
}
public void ModifySigningDictionary(PdfDictionary signDic)
{
}
}
Run Code Online (Sandbox Code Playgroud)
旁注:在所有这些iText样本中困扰我的是魔术数字(如此8192处)的存在,没有任何评论.这使得使用这个库变得更加困难和烦人.