无法使用 Apache PDFBOX 验证数字签名

2024-01-30

我是使用数字签名的新手。在其中一个项目中,我们使用 Apache PdfBox 来处理数字签名的 pdf 文件。虽然我们可以测试所有功能,但签名 pdf 文件的验证是我们无法破解的。我们使用 BouncyCastle 作为提供者。下面是代码:

从 pdf 文件中获取数字签名和签名内容:

byte[] signatureAsBytes = pdsignature.getContents(new FileInputStream(this.INPUT_FILE));
byte[] signedContentAsBytes = pdsignature.getSignedContent(new FileInputStream(this.INPUT_FILE));

数字签名验证:

Security.addProvider(new BouncyCastleProvider());
Signature signer = Signature.getInstance("RSA","BC");

//Get PublicKey from p7b file
X509Certificate cert509=null;
File file = new File("C:\\certificate_file.p7b");
FileInputStream fis = new FileInputStream(file);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Collection c = cf.generateCertificates(fis);
Iterator it = c.iterator();
PublicKey pubkey;

while (it.hasNext()) 
{
   cert509 = (X509Certificate) it.next();
   pubkey = cert509.getPublicKey();
}

boolean VERIFIED=false;
Security.addProvider(new BouncyCastleProvider());
Signature signer = Signature.getInstance("RSA","BC");
PublicKey key=this.getPublicKey(false);
signer.initVerify(key);

List<PDSignature> allsigs = this.PDFDOC.getSignatureDictionaries();
Iterator<PDSignature> i = allsigs.iterator();
    
while(i.hasNext())
{
        PDSignature sig = (PDSignature) i.next();
        byte[] signatureAsBytes = sig.getContents(new FileInputStream(this.INPUT_FILE));
        byte[] signedContentAsBytes = sig.getSignedContent(new FileInputStream(this.INPUT_FILE));
        signer.update(signedContentAsBytes);
        VERIFIED=signer.verify(signatureAsBytes);
}
    
System.out.println("Verified="+VERIFIED);

以下是 p7b 格式的证书的相关摘录 - 我使用 BouncyCastle 作为安全提供程序:

  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
  Key:  Sun RSA public key, 2048 bits
  Validity: [From: Tue Aug 06 12:26:47 IST 2013,
  To: Wed Aug 05 12:26:47 IST 2015]
  Algorithm: [SHA256withRSA]

使用上面的代码我总是得到“false”的响应。我不知道如何解决这个问题。请帮忙


您的主要问题是,有多种类型的 PDF 签名,其签名容器的格式以及实际签名字节的不同。另一方面,您的 BC 代码只能验证上述签名容器中包含的裸签名字节序​​列。

可互操作的签名类型

正如标题已经说明的那样,以下列表包含或多或少严格定义的“可互操作的签名类型”。这PDF规格 http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/PDF32000_2008.pdf指定一种还包含完全自定义签名方案的方法。但让我们假设我们处于可互操作的情况。签名类型的集合被简化为:

  • adbe.x509.rsa_sha1定义于ISO 32000-1 http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/PDF32000_2008.pdf第12.8.3.2节PKCS#1 签名;签名值Contents包含一个DER 编码的 PKCS#1 二进制数据对象;这个数据对象是一个相当裸露的签名,在 RSA 的情况下,是一个包含填充文档哈希和哈希算法的加密结构。

  • adbe.pkcs7.sha1定义于ISO 32000-1 http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/PDF32000_2008.pdf第12.8.3.3节PKCS#7 签名;签名值Contents包含一个DER 编码的 PKCS#7 二进制数据对象;该数据对象是一个大容器对象,它还可以包含元信息,例如它可能包含用于构建证书链的证书、用于证书吊销检查的吊销信息、用于修复签名时间的数字时间戳……文档字节范围的 SHA1 摘要应封装在 PKCS#7 SignedData 字段中,且 ContentInfo 类型为 Data。该 SignedData 的摘要应作为正常的 PKCS#7 摘要合并。

  • adbe.pkcs7.detached定义于ISO 32000-1 http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/PDF32000_2008.pdf第12.8.3.3节PKCS#7 签名;签名值Contents包含一个DER 编码的 PKCS#7 二进制数据对象, 往上看。文档字节范围内的原始签名消息摘要应作为正常的 PKCS#7 SignedData 字段合并。 PKCS#7 SignedData 字段中不得封装任何数据。

  • ETSI.CADES.分离定义于欧洲电信标准协会 TS 102 778-3 http://www.etsi.org/deliver/etsi_ts/102700_102799/10277803/01.02.01_60/ts_10277803v010201p.pdf并将融入 ISO 32000-2;签名值Contents包含一个CMS 中指定的 DER 编码 SignedData 对象; CMS 签名容器与 PKCS#7 签名容器关系密切,请参见上文。这本质上是 adbe.pkcs7.detached 的不同配置和更严格定义的变体。

  • 欧洲电信标准协会RFC3161定义于欧洲电信标准协会 TS 102 778-4 http://www.etsi.org/deliver/etsi_ts/102700_102799/10277804/01.01.02_60/ts_10277804v010102p.pdf并将融入 ISO 32000-2;签名值Contents包含一个RFC 3161 中指定的 TimeStampToken;时间戳令牌再次与 PKCS#7 签名容器密切相关,请参见上文,但它们包含特殊的数据子结构,其中包含文档哈希、时间戳创建时间以及发布时间服务器上的信息。

我建议研究我指定的规范以及其中引用的文档,主要是 RFC。基于这些知识,您可以轻松找到合适的 BouncyCastle 类来分析不同的签名Contents.

PS(2021):同时 ISO 32000-2 已发布,并且确实包含以下规范ETSI.CADES.分离 and 欧洲电信标准协会RFC3161。 PAdES 的 ETSI 技术规范 TS 102 778-* 已被实际规范 ETSI EN 319 142-* 取代。

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

无法使用 Apache PDFBOX 验证数字签名 的相关文章

随机推荐

  • 使用重复条目绘制置信区间和预测区间

    I have a correlation plot for two variables the predictor variable temperature on the x axis and the response variable d
  • 如何在 Rstudio 演示文稿中创建表格

    我正在尝试在 RStudio Rpres 文件中创建一个表 以下是我目前在网上搜索到的内容 但对齐不正确 这是最好的方法吗 关于对齐有什么建议吗 Test Right Left Default Center 12 12 12 12 123
  • 基本的多文件上传不适用于移动设备

    我创建了一个非常基本的多文件上传表单示例 参考 https bootsnipp com snippets kWqEj 它在桌面上运行完美 但在移动设备上运行不佳 至少在我测试的移动设备上是这样 On Mobile Xiaomi Mi4 An
  • 在 Eclipse 中配置 Logback

    我正在从 Log4j 切换到 Logback 但我还没有成功地使 Logback 工作 我已经放置了logback xml在我的 Eclipse Java 项目的根目录中 下面是其内容
  • 样式选择下拉框

    我有一个 HTML 选择下拉框 我已经对其进行了样式设置 我遇到的问题是我似乎无法设置选项的背景颜色样式 下面是演示的链接 您可以看到下拉选项有白色背景 我正在尝试更改它 http cssdeck com labs lnroxrua htt
  • 如何从 xml 获取垂直按钮视图

    我想在垂直方向创建一个按钮 也许我们可以通过扩展一个按钮并将画布重新渲染 旋转 到垂直方向 我们可以获得自定义按钮 但我需要从 xml 检查图形表示 我需要一个像这样的按钮 请参阅下面的链接 应该可以解决您的问题 http blog sty
  • 如何在ionic 3中使用jquery

    我正在尝试使用 ionic 3 中的 jquery 在 div 中加载外部网站 TS export class HomePage constructor public navCtrl NavController loadExternalUR
  • 将字符串扫描为十六进制字符数组

    这是我的示例代码 char a char str 20 unsigned char b 8 unsigned char c 8 int argsread int i init 8051 while 1 printf n enter a 64
  • Google 机器人使用 HTML5 模式路由在 AngularJS 网站上爬行

    我们有一个使用 HTML5 路由的 AngularJS 网站 我刚刚做了一些测试 Fetch as Google 运行 结果有点令人困惑 在获取选项卡上 我看到我们的网站在查看源代码中的样子 其中包含所有前端绑定 但并非所有呈现的 HTML
  • Eclipse - 轻松访问常用文件夹?

    有谁知道 Eclipse 在项目中使用 最喜欢的文件夹 的插件吗 我的项目 共有 1000 多个文件夹 中可能有 2 或 3 个文件夹 我经常在它们之间切换 每次使用 Project Explorer 中的滚动条来到达正确的文件夹确实很麻烦
  • 我可以使用什么工具来分析内存使用情况? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有一个使用 Visual Studio 2008 使用 C 编写的 Windows 应用程序 我想获取内存使用情况的统计信息 以查找内存
  • 重命名(别名)数组元素 C

    不确定什么是 良好实践 或被认为更 正确 我有一个数组 我想通过 arrayname 以外的名称访问各个元素 我可以使用 defines 或指针 也可能使用其他方式 Example define value1 myarray 1 int m
  • 在 html 电子邮件中发送个性化图像的推荐方式是什么?

    我知道已经有人问过类似的问题 但答案几乎总是相同的 您需要在服务器上共享图像并从电子邮件中链接到它 为了我的目的 我不能那样做 图像需要针对我发送电子邮件的每个用户进行个性化 因此将为每个用户动态生成电子邮件 并且不会始终相同 我无法共享图
  • LINQ to SQL 通配符

    如何在 LINQ To SQL lambda 表达式中构建通配符 这就是我目前所拥有的 var query from log in context Logs select log foreach string filter in Custo
  • 将列表项转换为元组

    我有一个这样的清单 February 01 2011 February 28 2011 March 01 2011 March 31 2011 我想将其转换为 February 01 2011 February 28 2011 March
  • 如何从数组中获取唯一值

    请注意这是针对 OSX 的 不适用于 iOS 我在其他问题中查看并尝试了一些解决方案 但似乎没有一个对我有用 因此 我想从数组中获取一组独特的年份 我的代码是这样的 NSMutableArray unique NSMutableArray
  • 使用 PEAR/Mail_Queue 发送 10,000 多封电子邮件的最佳方式

    我有一个 cron 它生成整个邮件信息并使用以下命令放入数据库表中 mail queue gt put 可以选择在发送电子邮件后将其删除 这是我需要一点帮助的地方 在获得上述信息后 发送电子邮件的最佳方式是什么 运行 mail queue
  • 自动布局:layoutMarginsGuide

    如何重写视觉格式 addConstraints NSLayoutConstraint constraintsWithVisualFormat label options AlignAllBaseline metrics nil views
  • 为什么我的列表项项目符号与浮动元素重叠

    我有一个 XHTML Strict 页面 其中我将图像与常规文本段落一起浮动 一切都很顺利 除非使用列表而不是段落 列表的项目符号与浮动图像重叠 更改列表或列表项的边距没有帮助 边距是从页面左侧开始计算的 但浮动会将列表项推到右侧insid
  • 无法使用 Apache PDFBOX 验证数字签名

    我是使用数字签名的新手 在其中一个项目中 我们使用 Apache PdfBox 来处理数字签名的 pdf 文件 虽然我们可以测试所有功能 但签名 pdf 文件的验证是我们无法破解的 我们使用 BouncyCastle 作为提供者 下面是代码