使用iTextSharp库提取pdf文件中包含的签名图像 [英] Extract images of signatures contained in a pdf file with iTextSharp library

查看:254
本文介绍了使用iTextSharp库提取pdf文件中包含的签名图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个签名的PDF文件。使用此功能,使用iTextSharp库,我找到证书p7m签名:

I have a signed PDF file. With this function, which makes use of iTextSharp library, I find the certificates p7m signatures:

        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);

        }
    }

现在......我怎么能提取与签名关联的图像(位图)?可能吗?
谢谢,Luigi

Now... how can I extract images (bitmap) associated to the signatures? Is it possible? Thanks, Luigi

推荐答案

在您的示例文档中,术语签名适用于三倍:

In your sample documents the term signature applies threefold:


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

  2. 相应的可视化包含一个位图图像手写签名。

  3. 相应的签名词典包含软件的专有信息,该信息将所有签名数据添加到PDF中。这些专有信息很可能包含OP评论中提到的生物特征数据。

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

According to the manufacturer of the software creating these multi-level signatures, the handwritten signature seems like the major proof of identity. The digital one only serves to protect the document from changes; it does not necessarily reflect the identity of the person who signed manually but instead of the owner of the device on which that manual signature was created ("Please sign here that you got the parcel"):


功能

手写签名捕获 - 签名板,支付终端,iPad或Android设备上的法定可识别签名。

Handwritten Signature Capturing - Forensically identifiable signatures on signature pads, payment terminals, the iPad or Android devices.

签名验证 - 比较手写签名预先注册的个人资料。

Signature Verification - Compare a handwritten signature against a pre-enrolled profile.

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

Control all steps in the signing process - Including positioning signature fields, filling out forms, adding annotations, adding attachments, and much more.

保护文件的完整性 - 用数字签名密封它们。

Protects the Integrity of Documents - By sealing them with a digital signature.

x yzmo英文网站首页

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

Concerning the extraction of all these information using iText...


  1. 如OP已经使用<$ c $的签名相关方法观察到的那样,可以轻松提取和验证数字签名的属性。 c> AcroFields class。

  2. 手写签名的位图图像也可以很容易地提取出来。签名表单字段字典的外观流仅绘制作为资源附加到流的位图。

  3. 也可以提取包含专有信息的数据容器,因为它是值

  4. 不幸的是,该数据容器的内容被打包到一个自称 EncryptedSignatureDataContainer <的XML片段中/ strong>即可。此XML片段的有效负载数据是否可以正确解密以及如何解释它是xyzmo人员自己请求的信息,我不知道他们是否公开这些信息。

  1. The properties of the digital signature can easily be extracted and verified as already observed by the OP using the signature related methods of the AcroFields class.
  2. The bitmap image of the handwritten signature can also be extracted fairly easily. The appearance stream of the signature form field dictionary merely paints that bitmap which is attached to the stream as a resource.
  3. The data container containing the proprietary information can also be extracted as it is the value of just another key in the signature dictionary.
  4. Unfortunately, though, the contents of that data container are packed into a XML fragment calling itself EncryptedSignatureDataContainer. Whether the payload data of this XML fragment can be properly decrypted and how it is to be interpreted is information to request from the xyzmo people themselves, and I have no idea if they consider that information public or not.

因此,最相关的信息是最不易访问的信息。

Thus, the most relevant information is the least accessible one.

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

PS Concerning the decryption of the encrypted biometric payload I found the following on the manufacturer's website:


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

The document contains a captured signature that has been encrypted (RSA 4096 + AES256). A person’s signature is encrypted immediately as it is captured by the signature pad, using the private key of a special certificate. This special certificate is selected by the company using the xyzmo suite, and is typically stored in a secure environment outside the company (bank safe, external notary, etc.). Thus, xyzmo itself has NO access to this certificate. For the encryption of signatures, the xyzmo suite just needs the public key of the certificate. It is only for decryption, and the extraction of signatures from a document, that the private key is required. Only specific people, to whom the company has granted access to this certificate, will be able to decrypt the profile using the PenAnalyst tool, which is provided as part of the suite.

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

因此,要解密生物识别数据,您必须能够访问通常属于的相应私钥存储在公司外部的安全环境中(银行保险箱,外部公证员等)。如果您有这种访问权限,我们可能会继续讨论这些解密数据的格式......;)

Thus, to decrypt the biometric data you have to have access to the respective private key which is typically stored in a secure environment outside the company (bank safe, external notary, etc.). If you have that kind of access, we may continue talking about the format of those decrypted data... ;)

顺便说一句,如果有人可以简单地从签名文件中检索生物识别数据,就可以很容易地将它们复制到其他文件中来伪造签名。

BTW, if anyone could simply retrieve the biometric data from the signed document, they could too easily be copied to other documents to fake a signature.

提取手写签名的位图图像

由于对手写签名的位图图像的提取特别感兴趣,这里提供了一个快速而又脏的帮助程序来提取签名图像。正如已经说过的,我在Java中这样做,因为我更喜欢在那里:

As there was special interest in the extraction of the bitmap image of the handwritten signature, here a quick and dirty helper to extract the image of the signature. As already said, I do it in Java as I'm more at home there:

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 真的是一个快速和肮脏的黑客。做了很多假设, null -checks被遗漏,...

Warning: The class XyzmoSignatureDataExtractor really is a quick&dirty hack. Many assumptions are made, null-checks are left out, ...

这篇关于使用iTextSharp库提取pdf文件中包含的签名图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆