当前位置: 首页 > 知识库问答 >
问题:

iTextSharp-如何获取用于签名的PDF内容,然后在以后进行签名

冯枫涟
2023-03-14

我正在开发一个客户机-服务器应用程序,其中客户机必须使用他们的签名签署PDF文档,并将它们上传到服务器。由于客户端没有将签名嵌入PDF的手段,他们只能读取原始字节并以原始字节的形式生成签名,因此任务变得复杂。

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

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

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

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

共有1个答案

傅新
2023-03-14

我自己想出来的。这段代码给我指明了正确的方向。

证明服务器上的进程必须如下所示:

  • 获取未签名的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, 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)
    {
    }
}
 类似资料:
  • 我关注以下帖子:iTextSharp-如何获取PDF内容进行签名,然后在以后进行签名,作为从PDF文档获取数据的基础,创建一个带有空白签名的临时文件,然后返回该临时文件的哈希值。散列被发送到在本地拥有令牌的客户端,在那里对其进行签名,并返回到签名的web应用程序。此时,我将其转换为字节并生成最终的签名文档。 但是,签名的文档没有有效的签名,显示消息:Error in decoding BER。 1

  • 我正在编写一个服务,其中我用一个空容器预签名pdf文件,从pdf文件中提取一个字节范围的散列,并将其发送到另一个服务,这将允许用户使用移动电话对散列进行签名。我拿回一个证书,我将注入到预签名pdf文件中的签名容器中。 签名本身起作用,数字签名是有效的,但我只需要更改可见签名本身的文本。我认为这是可能的,因为可见签名实际上与证书本身没有任何关系,所以显示来自证书的名称只是一种方便,特别是在多个签名的

  • 我正在尝试通过签名服务签署一个pdf文件。这个服务需要发送一个十六进制编码的SHA256摘要,作为回报,我会收到一个十六进制编码的SignatureValue。此外,我还收到了签名证书、中间证书、OCSP响应和TimeStampToken。但是,我在尝试使用SignatureValue对pdf进行签名时已经陷入了困境。 我读过布鲁诺的白皮书,过度浏览互联网,尝试了很多不同的方式,但签名不断出现无效

  • 我正在尝试使用远程web服务来演唱pdf,该服务返回一个XML签名,该签名由签名和最终用户证书组成。 我需要使用此签名通过IText签名对pdf进行签名,因为web服务。 所有IText示例都使用消息格式,但我不确定应该如何处理XML签名。 打开临时Pdf并嵌入接收到的签名的代码 从web服务返回的XML签名: 当我将返回的签名与上面的代码一起使用时,签名验证失败,出现“错误遇到时BER解码”。

  • 需要通过使用外部webservice对文档哈希进行签名来签署PDF,该过程必须在2个步骤中完成,并使用临时空签名。 在Priyanka问题和Grazina问题之后,阅读了那些帖子上的mkl答案,我现在有一个无效的签名,即使像Grazina那样添加了哈希前缀。 iTextSharp版本:5.5.13.1 这个节目是我上一个问题的另一个问题。当前代码(编译并开始调用SignPDF方法): 获得的结果

  • 我有一个场景,我需要用iText7库从pdf中获取签名信息。签名可能存在,也可能不存在。当我为没有任何数字签名的PDF实例化一个新的对象时,会出现异常 “没有相关的PdfWriter用于进行间接操作。” .如果有签名,就很好用。我不确定如何纠正这个异常。 更新为包含代码示例