我有一个pkcs#7文件,其中包含签名数据。它成功验证了:
$ openssl smime -verify -in data.p7s -CAfile root-certificate.pem
Verification successful
Signed data
但是当我提取签名部分时,我并没有看到它实际上与签名的内容相同。我指的是以下步骤:
$ openssl asn1parse -in data.p7s
...
35:d=4 hl=2 l= 9 prim: OBJECT :pkcs7-data
46:d=4 hl=2 l=inf cons: cont [ 0 ]
48:d=5 hl=2 l=inf cons: OCTET STRING
50:d=6 hl=2 l= 5 prim: OCTET STRING :(my data is here in plaintext)
...
(then the signed block starts:)
2861:d=6 hl=2 l= 9 prim: OBJECT :rsaEncryption
2872:d=6 hl=2 l= 0 prim: NULL
2874:d=5 hl=4 l= 256 prim: OCTET STRING [HEX DUMP]:<signed data is here>
我使用签名数据剪切[HEX DUMP]
:
$ dd if=data.p7s of=signed-part.bin bs=1 skip=2878 count=256
使用相应的公钥解密:
$ openssl rsautl -verify -in signed-part.bin -pubin -inkey root-public-key.pem -out verified-data.bin
并查看结果:
$ openssl asn1parse -inform der -in verified-data.bin
0:d=0 hl=2 l= 33 cons: SEQUENCE
2:d=1 hl=2 l= 9 cons: SEQUENCE
4:d=2 hl=2 l= 5 prim: OBJECT :sha1
11:d=2 hl=2 l= 0 prim: NULL
13:d=1 hl=2 l= 20 prim: OCTET STRING [HEX DUMP]:<hash here>
此[HEX DUMP]
不原始数据的SHA1总和。
我不明白为什么哈希是不同的。显然,它是与原始数据不同的散列。哈希是否也涵盖任何“经过身份验证的属性”?如果是,如何查看已经散列并签名的确切属性是什么?
答案 0 :(得分:4)
好的,你没有提供完整的样本,但我会尝试使用不同的样本导航你。
OpenSSL asn1parse
无法识别经过身份验证的属性。您可以使用OpenSSL cms
:
openssl cms -in data.p7s -noout -cmsout -print
查找signedAttrs
(“已签名的属性”是现在调用“经过身份验证的属性”的方式,在CMS术语中)
看起来像这样:
...
signerInfos:
...
signedAttrs:
object: contentType (1.2.840.113549.1.9.3)
value.set:
OBJECT:pkcs7-data (1.2.840.113549.1.7.1)
object: signingTime (1.2.840.113549.1.9.5)
...
现在返回asn1parse
输出,找到相应的部分,如下所示:
...
1343:d=5 hl=3 l= 216 cons: cont [ 0 ]
1346:d=6 hl=2 l= 24 cons: SEQUENCE
1348:d=7 hl=2 l= 9 prim: OBJECT :contentType
1359:d=7 hl=2 l= 11 cons: SET
1361:d=8 hl=2 l= 9 prim: OBJECT :pkcs7-data
1372:d=6 hl=2 l= 28 cons: SEQUENCE
1374:d=7 hl=2 l= 9 prim: OBJECT :signingTime
...
(对于这个漂亮的缩进,添加-i
选项)
现在,在这种情况下,提取(dd ...
)数据,包括DER上下文标记头,即偏移1343,长度219。然后用0xa0
替换开头的0x31
字节。为什么必须这样做,在DER encoding - How to convert implicit tag to explicit tag或RFC5652, section 5.4
此数据的sha1哈希现在应该匹配。