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

使用iTextSharp库提取包含在pdf文件中的签名图像

景令秋
2023-03-14

我有一个签名的PDF文件。有了这个功能,它利用了iTextSharp库,我找到了证书p7m签名:

        private void GetSignature(string FileName)
    {
        AcroFields acroFields = new PdfReader(FileName).AcroFields;
        List<string> names = acroFields.GetSignatureNames();

        foreach (var name in names)
        {
            PdfDictionary dict = acroFields.GetSignatureDictionary(name);
            PdfString contents = (PdfString)PdfReader.GetPdfObject(dict.Get(PdfName.CONTENTS));

            byte[] PKCS7 = contents.GetOriginalBytes();
            ByteArrayToFile(@"c:\signature\" + name + ".p7m", PKCS7);

        }
    }

现在...我如何提取与签名相关的图像(位图)?可能吗?谢谢,路易吉

共有1个答案

爱亮
2023-03-14

在您的样本文件中,签名一词适用于三个方面:

  1. 它包含符合PDF规范ISO 32000-1:2008的数字签名

根据创建这些多级签名的软件制造商的说法,手写签名似乎是身份的主要证明。数字文件仅用于保护文件不受更改;它不一定反映手动签名者的身份,而是反映创建手动签名的设备的所有者(“请在此处签名,说明您收到了包裹”):

功能

手写签名捕获——签名板、支付终端、iPad或Android设备上的法医识别签名。

签名验证-将手写签名与预注册的配置文件进行比较。

控制签名过程中的所有步骤,包括定位签名字段、填写表单、添加批注、添加附件等等。

通过使用数字签名密封文档,保护文档的完整性。

(xyzmo英文网站首页)

关于使用iText提取所有这些信息。。。

  1. 使用AcroFields类的签名相关方法,可以很容易地提取和验证OP已经观察到的数字签名的属性。
  2. 手写签名的位图图像也可以很容易地提取出来。签名表单字段字典的外观流只是将附加到流的位图绘制成资源。
  3. 还可以提取包含专有信息的数据容器,因为它只是签名字典中另一个键的值。
  4. 然而,不幸的是,该数据容器的内容被打包到一个XML片段中,该片段自称为EncryptedSignatureDataContainer。这个XML片段的有效负载数据是否可以正确解密,以及如何解释它,这些信息需要从xyzmo人员自己那里请求,我不知道他们是否认为这些信息是公开的。

因此,最相关的信息是最难获取的信息。

PS关于加密生物识别有效载荷的解密,我在制造商的网站上发现了以下内容:

该文档包含一个已被加密的捕获签名(RSA 4096 AES256)。一个人的签名在被签名垫捕获时立即被加密,使用特殊证书的私钥。该特殊证书由使用xyzmo套件的公司选择,通常存储在公司外部的安全环境中(银行保险箱、外部公证人等)。因此,xyzmo本身没有访问该证书的权限。对于签名的加密,xyzmo套件只需要证书的公钥。只有在解密和从文档中提取签名时,才需要私钥。只有公司授权访问此证书的特定人员才能使用作为套件一部分提供的PenAnalyst工具解密个人资料。

(xyzmo英文网站数字签名捕获常见问题解答)

因此,要解密生物特征数据,您必须访问各自的私钥,该私钥通常存储在公司外部的安全环境中(银行保险箱、外部公证人等)。如果你有这种访问权限,我们可以继续讨论这些解密数据的格式…;)

顺便说一句,如果任何人都可以简单地从签署的文件中检索生物特征数据,他们很容易被复制到其他文件中以伪造签名。

提取手写签名的位图图像

由于人们对提取手写签名的位图图像特别感兴趣,这里有一个快速而肮脏的助手来提取签名图像。如前所述,我在Java中做这件事,因为我在那里更自在:

public class XyzmoSignatureDataExtractor
{
    public XyzmoSignatureDataExtractor(PdfReader reader)
    {
        this.reader = reader;
    }

    public PdfImageObject extractImage(String signatureName) throws IOException
    {
        MyImageRenderListener listener = new MyImageRenderListener();

        PdfDictionary sigFieldDic = reader.getAcroFields().getFieldItem(signatureName).getMerged(0);
        PdfDictionary appearancesDic = sigFieldDic.getAsDict(PdfName.AP);
        PdfStream normalAppearance = appearancesDic.getAsStream(PdfName.N);

        PdfDictionary resourcesDic = normalAppearance.getAsDict(PdfName.RESOURCES);
    
        PdfContentStreamProcessor processor = new PdfContentStreamProcessor(listener);
        processor.processContent(ContentByteUtils.getContentBytesFromContentObject(normalAppearance), resourcesDic);        

        return listener.image;
    }

    class MyImageRenderListener implements RenderListener
    {
        public void beginTextBlock() { }

        public void endTextBlock() { }

        public void renderImage(ImageRenderInfo renderInfo)
        {
            try
            {
                image = renderInfo.getImage();
            }
            catch (IOException e)
            {
                throw new RuntimeException("Failure retrieving image", e);
            }
        }

        public void renderText(TextRenderInfo renderInfo) { }

        PdfImageObject image = null;
    }

    final PdfReader reader;
}

你这样使用它:

PdfReader reader = new PdfReader(resourceStream);
XyzmoSignatureDataExtractor extractor = new XyzmoSignatureDataExtractor(reader);
AcroFields acroFields = reader.getAcroFields();

for (String name: acroFields.getSignatureNames())
{
    System.out.printf("\nTesting signature '%s'.\n", name);
    PdfImageObject image = extractor.extractImage(name);

    OutputStream os = new FileOutputStream("target/test-outputs/SampleXyzmoSignature-image-" + name + "." + image.getFileType());
    os.write(image.getImageAsBytes());
    os.close();

    PdfDictionary imageDictionary = image.getDictionary();
    PRStream maskStream = (PRStream) imageDictionary.getAsStream(PdfName.SMASK);
    if (maskStream != null)
    {
        PdfImageObject maskImage = new PdfImageObject(maskStream);

        os = new FileOutputStream("target/test-outputs/SampleXyzmoSignature-image-" + name + "-mask." + maskImage.getFileType());
        os.write(maskImage.getImageAsBytes());
        os.close();
    }
}

警告:类XyzmoSignatureDataExtractor确实是一个快速

 类似资料:
  • 我想知道我们如何使用ITEXT7来提取与数字签名相关的图像信息。我知道过去也有人问过类似的问题,但它们大多是围绕ITEXT5提出的,在对软件进行了所有更新和修改后,这与ITEXT7大不相同。

  • 我正在编写一个服务,其中我用一个空容器预签名pdf文件,从pdf文件中提取一个字节范围的散列,并将其发送到另一个服务,这将允许用户使用移动电话对散列进行签名。我拿回一个证书,我将注入到预签名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方法): 获得的结果

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

  • 我对iTextSharp有意见。我有一个带有表单字段的文档,并且我已经为签名生成了字段。当第一个人在文件上签字时,它就会正常工作。Adobe Reader显示有效签名。当我让第二个人在文档上签名时,Adobe Reader显示签名1现在是“未知签名”,签名无效。Adobe reader显示: 此签名中包含的格式或信息有错误(支持信息:SigDict/Contents非法数据)