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

2023-12-28

我有一个签名的 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. 它包含根据 PDF 规范的数字签名ISO 32000-1:2008 http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/PDF32000_2008.pdf.
  2. 相应的可视化包含手写签名的位图图像。
  3. 相应的签名字典包含将所有签名数据添加到 PDF 的软件的专有信息。这些专有信息很可能包含 OP 评论中提到的生物识别数据。

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

功能

手写签名采集- 签名板、支付终端、iPad 或 Android 设备上的可法医识别的签名。

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

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

保护文件的完整性- 通过使用数字签名对其进行密封。

(xyzmo英文网站首页 http://www.xyzmo.com/en/Pages/xyzmostart.aspx)

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

  1. 数字签名的属性可以很容易地提取和验证,正如 OP 使用 OP 的签名相关方法所观察到的那样。AcroFields class.
  2. 手写签名的位图图像也可以相当容易地提取。签名表单字段字典的外观流仅绘制作为资源附加到流的位图。
  3. 还可以提取包含专有信息的数据容器,因为它只是签名字典中另一个键的值。
  4. 但不幸的是,contents该数据容器的一部分被打包到一个调用自身的 XML 片段中加密签名数据容器。该XML片段的有效负载数据是否可以正确解密的如何解释它是 xyzmo 人自己要求的信息,我不知道他们是否认为该信息是公开的。

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

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

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

(xyzmo 英文网站 数字签名捕获常见问题解答 http://www.xyzmo.com/en/resource-center/Pages/DigitalSignatureFAQ.aspx)

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

顺便说一句,如果任何人都可以简单地从签名文档中检索生物识别数据,那么它们很容易被复制到其他文档中以伪造签名。

提取手写签名的位图图像

由于人们对提取手写签名的位图图像特别感兴趣,因此这里有一个快速而肮脏的助手来提取签名的图像。正如已经说过的,我用 Java 来做,因为我更熟悉 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();
    }
}

Warning:班上XyzmoSignatureDataExtractor确实是一个快速而肮脏的黑客。做了很多假设,null-支票被遗漏了,...

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • mysql TIME_WAIT;连接数过多问题

    当我在现场检查 mysql 加载时间时 我得到的结果显示连接为 TIME WAIT 即使我关闭了每个页面上的连接 有时网站无法加载 表示连接太多 有什么办法可以解决这个问题 预先感谢您的任何回复或建议 如果客户端连接到 MySQL 服务器
  • 使用 imshow 打印一种颜色 [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我想使用 RGB 值在屏幕上打印颜色 并且输出应该只是单一颜色 例如 如果我给出红色的 RGB 值 我希望输出显示红色
  • 如何在 Keras 中使用 model.reset_states() ?

    我有顺序数据 并且声明了一个 LSTM 模型来预测y with x在喀拉斯 所以如果我打电话model predict x1 and model predict x2 调用是否正确model reset states两者之间predict
  • 如何使用 SwiftUI 在视图上检测向上、向下、向左和向右滑动

    我正在着手构建 Apple Watch 应用 我目前正在做的工作将要求我利用检测四个主要方向的滑动 UP DOWN LEFT and RIGHT 问题是我不知道如何检测到这一点 我环顾四周 发现自己走进了死胡同 我可以对下面的视图做什么才能
  • JQuery UI 翻转文本,就像gumroad.com [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我试图在我
  • 在 Chapel 文件中包含第二个源文件

    在 C 中 当我需要 actions cpp 中的类时classes cpp我包括标题 例如 include
  • 如何读取和遍历 inode

    我已经在 EXT2 文件系统中打开了超级块和组描述符 但我不知道如何读取根目录或其中的文件 这是我得到的一些内容 fd open dev sdb2 O RDONLY lseek fd SuperSize SEEK SET read fd s
  • 创建一个可以在 React 上拖放列和行的表格

    我想创建一个可以在 React 上拖放列和行的表格 我看过其他解决方案 例如反应美丽 dnd https github com atlassian react beautiful dnd 表格拖动器 https github com sin
  • 如何从非组件辅助函数访问 redux 的存储?

    我有一个辅助函数 当我想从 Redux 存储中删除某些内容时 我会调用它 但是 我需要能够访问函数内的当前存储 以确定下一步要做什么 这就是我想做的 export function deleteDocument id this props
  • 如何制作自己的 P2P 软件? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我怎样才能制作自己的napster 这些 p2p 程序使用哪个库 我不太熟悉套接字编程的概念 你能用Qt4制作p2p程序吗 从 Napst
  • Instagram 风格的多媒体列表视图

    我尝试过搜索但没有找到明确的答案 我想知道创建一个列表视图的最佳方法 该列表视图可以使用媒体控制器显示音频 视频视图项目 用户可以为每个项目播放 暂停等 我认为实现纹理视图将是前进的方向 我相信视频视图与滚动视图不能很好地配合 但我不确定从
  • 如何在 Json.NET 中使用 JsonSerializerSettings 在属性中指定时禁用 TypeNameHandling?

    有时我需要抑制输出 type 即使由 Json NET 指定属性JsonPropertyAttribute ItemTypeNameHandling https www newtonsoft com json help html P New
  • 检查字符串是否仅包含 utf8 字母

    我一直在寻找一种用 Javascript 处理这些东西的方法 PHP 有一个处理 unicode 字符的库 称为Unicode 字符属性 http php net manual en regexp reference unicode php
  • 恢复0的SKPhysicsBody仍然会反弹

    我正在尝试以恒定速度掉落 SKSpriteNode 并且不会弹跳 这是我正在使用的代码 SKSpriteNode floor SKSpriteNode spriteNodeWithColor UIColor clearColor size
  • slim php框架 图片上传放入数据库

    我是 slim php 框架的新手 我想上传图像并将文件名放入数据库中POST 有人可以给我一些示例代码吗 这是路由器 app gt post uploadFile 这将指向下面的函数 function uploadFile if isse
  • HttpListener 被调用两次

    我正在使用此代码来实现 Http Server public Server httpListener new HttpListener httpListener Prefixes Add Server UriAddress StartSer
  • ASP .Net:AspNetSqlMembershipProvider“唯一电子邮件”问题

    我在 ASP Net 4 Web 应用程序项目中使用 AspNetSqlMembershipProvider 我已在 web config 文件中将用户地址配置为唯一 requiresUniqueEmail true 如下所示
  • linux/list.h 中container_of 宏背后的基本原理

    在linux内核列表中的实现 include linux list h 第一行 粘贴在下面 背后的基本原理是什么container of macro const typeof type 0 gt member mptr ptr 在我的示例代
  • mysql交叉连接,但没有重复对?

    假设我的表中有以下行 表行 id 63 64 65 66 67 68 如果我运行以下查询 我会得到 30 行 SELECT r1 id r2 id FROM rows AS r1 CROSS JOIN rows AS r2 WHERE r1
  • 使用 iTextSharp 库提取 pdf 文件中包含的签名图像

    我有一个签名的 PDF 文件 通过这个使用 iTextSharp 库的函数 我找到了证书 p7m 签名 private void GetSignature string FileName AcroFields acroFields new