OpenSSL PKCS7验证失败:SMIME签名与ASN1及载荷摘要关联问询
我来帮你拆解这个SMIME验证的问题,一步步理清楚:
核心关联:PEM的ASN.1结构与载荷摘要的关系
是的,SMIME签名(基于PKCS#7格式)的ASN.1结构里明确包含了原始载荷的加密摘要,这是签名验证的核心依据。当你生成SMIME签名时,工具会先计算原始载荷的哈希值(比如SHA1),然后用私钥对这个哈希值加密生成签名;而验证时,工具会重新计算载荷的哈希,和ASN.1结构里存储的原始哈希对比,同时验证签名的有效性。
能否在asn1parse输出中找到与sha1sum对应的哈希值?
完全可以,但你需要找对ASN.1结构里的对应字段。具体步骤:
- 用带缩进的ASN.1解析命令查看结构:
openssl asn1parse -in your_smime.pem -i - 在输出中定位到
PKCS7->SignedData->SignerInfo节点下的两个关键部分:DigestAlgorithmIdentifier:会显示你使用的哈希算法(比如sha1)- 紧随其后的
OCTET STRING:这个字段的十六进制值就是原始载荷的SHA1哈希
举个典型的输出片段:
166:d=4 hl=2 l= 9 cons: SEQUENCE 168:d=5 hl=2 l= 5 prim: OBJECT :sha1 175:d=5 hl=2 l= 0 prim: NULL 177:d=3 hl=2 l= 20 prim: OCTET STRING [HEX DUMP]:A1B2C3D4E5F6A7B8C9D0E1F2A3B4C5D6E7F8A9B0
这里[HEX DUMP]后的字符串,就是和你用sha1sum计算的载荷哈希完全对应的值(注意大小写统一即可)。
解决OpenSSL的“PKCS7, verification failure, checksum of payload in PEM?”错误
这个提示本质是说计算出的载荷哈希和ASN.1结构里存储的哈希不匹配,常见原因和排查方法:
1. 你计算哈希的载荷和签名时的原始载荷不一致
这是最常见的问题,比如:
- 你直接计算了原始明文的哈希,但SMIME签名里的载荷是经过MIME编码(比如base64)或格式转换后的内容
- 换行符差异(Windows的CRLF vs Linux的LF)、额外空格/空行等细微修改
解决方法:先从SMIME PEM中提取出签名时使用的原始载荷,再计算哈希:
openssl smime -verify -in your_smime.pem -noverify -out extracted_payload.txt sha1sum extracted_payload.txt
(-noverify参数是跳过签名验证,只提取载荷)
2. 哈希算法不匹配
比如你用sha1sum计算SHA1,但签名实际用的是SHA256/SHA3等算法,导致找不到对应摘要。可以通过asn1parse的DigestAlgorithmIdentifier确认算法,再用对应工具计算(比如sha256sum)。
3. PEM文件本身损坏
如果PEM文件格式错误、缺失关键ASN.1字段,也会导致验证失败。可以先检查PEM的格式是否正确,比如开头是-----BEGIN PKCS7-----,结尾是-----END PKCS7-----,中间的base64内容没有换行错误。
4. 签名验证的其他环节问题
如果载荷哈希和ASN.1里的摘要一致,但还是验证失败,那问题可能出在证书信任链(比如验证用的公钥证书不被信任)、签名私钥和验证公钥不匹配等,这时候可以去掉-noverify参数,查看更详细的错误提示:
openssl smime -verify -in your_smime.pem -CAfile trusted_certs.pem
内容的提问来源于stack exchange,提问作者chris01

