You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取带数字签名PE文件的原始PE哈希值?

如何从带Authenticode签名的PE文件中提取原始PE哈希值

我完全懂你的痛点——要拿到签名绑定的原始PE哈希(而非整个文件的哈希),但微软没明确定义Authenticode PKCS#7块里ContentInfo的具体结构,直接重新计算哈希对篡改后的文件又毫无意义。下面是可行的解决方案,核心是解析PKCS#7签名结构里的特定属性:

核心原理回顾

Authenticode的PKCS#7签名块里,原始PE的哈希值其实存储在SignerInfo的AuthenticatedAttributes中的SpcPeImageData属性(OID: 1.3.6.1.4.1.311.2.1.15),而非ContentInfo的顶层字段——你提到的ContentInfo只是PKCS#7的外层容器,真正的关键数据在内部的签名属性里。

具体提取步骤

  • 定位PE文件中的Authenticode签名块
    PE文件的可选头目录项IMAGE_DIRECTORY_ENTRY_SECURITY会指向签名块的偏移和大小。这个块是DER编码的PKCS#7 SignedData结构,直接提取这部分数据即可,不用处理整个PE文件的其他内容。
  • 解析PKCS#7 SignedData结构
    首先识别ContentInfo的OID(应该是1.3.6.1.4.1.311.2.1.4,对应Authenticode的SignedData),跳过外层容器,进入SignedData部分;然后找到SignerInfo数组(通常只有一个元素),遍历其中的AuthenticatedAttributes集合。
  • 提取SpcPeImageData属性中的哈希值
    在AuthenticatedAttributes中找到OID为1.3.6.1.4.1.311.2.1.15的属性,它的ASN.1编码内容包含哈希算法的OID(比如SHA-256对应2.16.840.1.101.3.4.2.1)和原始PE文件的哈希字节数组,直接提取这个字节数组并转成十六进制字符串,就是你要的原始PE哈希。

实现思路(工具/代码)

  • Windows平台原生方案:使用CryptQueryObject API加载PE文件的签名,获取PKCS#7消息对象,再通过CryptMsgGetParam提取SignerInfo和对应的属性,最后解析ASN.1结构拿到哈希。
  • 跨平台方案:用OpenSSL的PKCS7_*系列函数解析签名块的DER数据,定位到SignerInfo的属性节点,手动解析SpcPeImageData的内容。

关键提醒

为什么重新计算哈希没用?因为篡改后的PE文件,重新计算的是当前修改后的文件哈希,而签名里的哈希是签名时原始PE的哈希——两者必然不一致,只有从签名块里提取的才是签名绑定的原始值。

内容的提问来源于stack exchange,提问作者dockd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:27:29