微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – iTextSharp – 如何获取用于签名的PDF内容,然后在以后签名

我正在开发一个客户端 – 服务器应用程序,客户端必须使用签名对PDF文档进行签名并将其上载到服务器.由于客户端无法将签名嵌入到PDF中,因此它们只能读取原始字节并以原始字节的形式生成签名,这使得任务变得复杂.

我正在尝试实现以下工作流程:

>客户端将未签名的PDF上载到服务器
>服务器打开PDF,提取客户端需要签名的字节,然后将这些字节发回
>客户端接收这些字节,使用客户端证书对其进行签名,然后将签名发送到服务器
>服务器将收到的签名嵌入到之前收到的PDF中.

我发现了一些提取字节的代码示例,用于签名并将签名字节嵌入PDF(this is the main sample I’m using).

问题是这个示例执行一个程序中的所有步骤,它在获取文档哈希后立即嵌入签名而不关闭pdfstamper.我需要的是在添加签名字段并获取sha.Hash之后保存文档的某种方式,然后在稍后的某个时间(当服务器收到计算的签名时)打开文档并将签名值嵌入到PDF中.

您能否建议一种修改代码方法,以便步骤(2)和(4)可以独立,并且不需要PdfReader和pdfstamper的共享实例?

解决方法

自己搞清楚了. This piece of code向我指出了正确的方向.

原来服务器上的进程必须如下:

>获取未签名的PDF并添加一个空的签名字段
>根据文件修改内容计算需要签名的字节
>将带有空签名的已修改PDF保存到临时文件
>将计算的字节发送到客户端
>当客户端使用签名响应时,打开临时文件并将签名插入到先前创建的字段中

相关的服务器代码

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,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)
    {
    }
}

旁注:在所有这些iText样本中困扰我的是魔术数字的存在(如8192这里),没有任何评论.这使得使用这个库变得更加困难和烦人.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐