我正在开发一个 PDF 签名工具。为此,我将获得 PKCS#1 格式的 PDF 签名 sha256 数据和来自设备的证书,我需要使用这两个来嵌入 PDF。大多数 PDF 阅读器仅支持 PKCS#7 签名。
有没有办法将 PKCS#1 签名转换为 PKCS#7 签名(使用证书文件)?
我知道 PKCS#7 = 证书 + 可选原始数据 + PKCS#1 格式的签名
我正在开发一个 PDF 签名工具。为此,我将获得 PKCS#1 格式的 PDF 签名 sha256 数据和来自设备的证书,我需要使用这两个来嵌入 PDF。大多数 PDF 阅读器仅支持 PKCS#7 签名。
有没有办法将 PKCS#1 签名转换为 PKCS#7 签名(使用证书文件)?
我知道 PKCS#7 = 证书 + 可选原始数据 + PKCS#1 格式的签名
您的问题有些过于简单化了这种情况。
关于 PKCS#7 <-> PKCS#1:
是的,PKCS#7 签名容器包含 SignerInfo 对象,这些对象分别基本上包含 PKCS#1 样式签名和一些属性。但是这种 PKCS#1 样式签名通常不仅仅是对文档数据进行签名,而是对所谓的“签名属性”结构进行签名。其中之一是文档哈希,其他可以是签名时间、签名者证书的链接以及其他信息;在许多用例中都需要这些额外信息。只有最原始构建的 SignerInfo 结构直接对文档数据进行签名。
因此,一般来说,如果您只是简单地获取一些数据的 PKCS#1 签名并将其包装在 PKCS#7 容器中,则不会接受该签名容器。
有关详细信息,请参阅RFC 3852。
关于集成 PDF 签名:
您对即将实现的描述有些模糊。您似乎认为要签名的文档哈希是原始 PDF 的哈希。在集成 PDF 签名的情况下,这是错误的:为了创建集成 PDF 签名,您首先通过一些数据扩展 PDF,这些数据包含 PKCS#7 签名容器(由规范推荐)或 PKCS#1 签名的占位符集成。然后,您需要散列除占位符之外的扩展 PDF。(根据当前的 PDF 规范,您可以散列小于该值,但这不会被当前的 Adobe Acrobat/Reader 接受,也不应该被任何认真的验证者接受)。
有关详细信息,请参阅Adobe 发布的 ISO 32000-1:2008
根据法律要求,您可能还必须考虑 ETSI 指定的 PDF 高级电子签名 (PAdES),参见 符合欧盟标准的电子签名的 ETSI 标准。这些将成为 ISO 32000-2(又名 PDF 2.0)的一部分。
那么,您是否仍然确定您的用例允许您想到的那些非常简单的 PKCS#7 签名,并且您的 PKCS#1 源签名是否为正确的文档创建?在这种情况下,通过查看RFC 3852可以轻松构建这些容器。
无论如何,您应该看看Bruno Lowagie (iText Software)的 PDF 文档数字签名白皮书。
查看 RFC 3852 > 5.4。消息摘要计算过程
只要其中没有签名属性,就可以简单地将 PKCS#1 转换为 PKCS#7。如果有,那么您将被卡住,因为 PKCS#1 仅隐藏内容的哈希值,而 PKCS#7 具有构造中间结构所需的签名属性,并且该结构的哈希值正在被签名。