了解可执行文件签名

在 Windows 中,文件的数字签名可以存储在目录签名、嵌入签名或两者中。 目录签名是包含一个或多个其他文件的签名的文件,而嵌入的签名存储在特定于文件格式的结构中,允许在文件本身的字节中嵌入签名。 例如,Windows 可移植可执行文件(PE)文件格式 允许在数据目录部分嵌入证书表;签名数据包含文件的代码组件的签名哈希。

签名计算

受文件签名保护的特定字节因用于生成和以后验证给定文件类型的签名的使用者接口包(SIP)而异。 Windows 的签名基础结构是可扩展的,允许第三方 注册其他 SIP ,以支持对其他文件类型进行签名,这些文件类型超出了 Windows 包含的可签名格式。

对于未安装 SIP 的文件类型,文件的整个内容可能会被哈希处理(如文本文件的情况),并存储在目录文件中。

对于 SIP 支持的文件类型(如 Windows 可移植可执行文件(PE)文件,SIP 可能会从哈希计算中排除文件的某些部分,并且可以将生成的签名存储在文件本身或单独的目录文件中。 在 Windows PE 文件中,数字签名可以“嵌入”到可选标头数据目录中的证书表条目指定的位置。 当 Authenticode 用于对 Windows PE 文件进行签名时,计算文件的哈希值的算法将排除某些 PE 字段。 在文件中嵌入签名时,签名过程可以修改这些字段,而不会影响文件的哈希值。

生成待签名内容的哈希后,将使用签名证书对其进行签名,从而允许在将来验证哈希未被修改,并且文件中哈希的部分自签名后保持不变。

安全隐患

PE 文件的软件发布者信任提供程序 SIP 对文件的可执行内容进行哈希处理,但故意不包含文件的校验和(因为在嵌入签名时会发生变化)和证书表目录(签名时会由文件的签名填充)。

在计算签名时,软件发布者信任提供程序 SIP 不会对文件的所有字节(即不是“平面文件哈希”)进行哈希处理,这意味着可以在不中断其签名的情况下将其他内容嵌入已签名的 PE 文件中。 例如,某些服务通过将元数据存储在WIN_CERTIFICATE结构中的 PKCS#7 填充区域中、向签名添加未评估的属性或添加使用自签名证书签名的额外签名,将 元数据嵌入已签名 的软件安装程序中。 其中每种方法都会带来风险。 虽然注入的内容不是直接可执行的,但易受攻击的应用程序可能会错误地期望它可信(因为文件的其余部分已正确签名),并对其执行作。

这种无符号嵌入能力自 2013 年以来一直被攻击者利用,为了解决 CVE-2013-3900 漏洞,引入了 EnableCertPaddingCheck 注册表覆盖功能。 当 EnableCertPaddingCheck DWORD 存在并设置为 1 时, WinVerifyTrust 将验证WIN_CERTIFICATE结构中的所有 PKCS#7 填充字节是否设置为 0。 如果找到其他值,SIP 将认为签名无效。

关于目录签名的备注

目录签名验证不能支持所有 SIP。 验证目录签名文件时,仅加载 SIP 以对 PE 和 CAB 文件类型进行签名和验证。 使用平面文件哈希对其他文件类型进行签名和验证。

启用 EnableCertPaddingCheck 注册表项不会影响 WinVerifyTrust 对目录签名 PE 文件的评估。 如果可执行文件是目录签名的,则不会检查嵌入的签名,因此即使设置了 EnableCertPaddingCheck 注册表项,也不会评估证书填充是否存在意外内容。

验证码签名注意事项