我对ASN.1格式很陌生。我有一个PKCS#7签名,该签名在执行ASNdump之后如下所示。有人可以帮助我了解以下每个元素的含义吗?我只能在签名中标识2个证书,但不能确认哪个证书用于什么。如果您能阐明我应该如何解码,验证此签名并解密数据,也请多加赞赏。
0 904: SEQUENCE {
4 9: OBJECT IDENTIFIER signedData (1 2 840 113549 1 7 2)
15 889: [0] {
19 885: SEQUENCE {
23 1: INTEGER 1
26 11: SET {
28 9: SEQUENCE {
30 5: OBJECT IDENTIFIER sha1 (1 3 14 3 2 26)
37 0: NULL
: }
: }
39 404: SEQUENCE {
43 9: OBJECT IDENTIFIER envelopedData (1 2 840 113549 1 7 3)
54 389: [0] {
58 385: SEQUENCE {
62 1: INTEGER 0
65 348: SET {
69 344: SEQUENCE {
73 1: INTEGER 0
76 63: SEQUENCE {
78 43: SEQUENCE {
80 11: SET {
82 9: SEQUENCE {
84 3: OBJECT IDENTIFIER countryName (2 5 4 6)
89 2: PrintableString 'US'
: }
: }
93 12: SET {
95 10: SEQUENCE {
97 3: OBJECT IDENTIFIER organizationName (2 5 4 10)
102 3: PrintableString 'ABC'
: }
: }
107 14: SET {
109 12: SEQUENCE {
111 3: OBJECT IDENTIFIER commonName (2 5 4 3)
116 5: PrintableString 'CA'
: }
: }
: }
123 16: INTEGER 0A 01 41 7E 00 74 01 51 8F 8F 74 7E 8F 4D A6 B5
: }
141 13: SEQUENCE {
143 9: OBJECT IDENTIFIER rsaOAEP (1 2 840 113549 1 1 7)
154 0: SEQUENCE {}
: }
156 257: BIT STRING
: C2 A1 7A FA B2 08 1C CC CA BB 46 96 FA 1D 84 6C
Truncated
: }
: }
417 28: SEQUENCE {
419 9: OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
430 15: SEQUENCE {
432 7: OBJECT IDENTIFIER '1 2 840 10047 1 1'
441 4: SEQUENCE {
443 2: BIT STRING 6 unused bits
: '10'B (bit 1)
: }
: }
: }
: }
: }
: }
447 457: SET {
451 453: SEQUENCE {
455 1: INTEGER 1
458 63: SEQUENCE {
460 43: SEQUENCE {
462 11: SET {
464 9: SEQUENCE {
466 3: OBJECT IDENTIFIER countryName (2 5 4 6)
471 2: PrintableString 'US'
: }
: }
475 12: SET {
477 10: SEQUENCE {
479 3: OBJECT IDENTIFIER organizationName (2 5 4 10)
484 3: PrintableString 'ABC'
: }
: }
489 14: SET {
491 12: SEQUENCE {
493 3: OBJECT IDENTIFIER commonName (2 5 4 3)
498 5: PrintableString 'CA'
: }
: }
: }
505 16: INTEGER 40 01 58 68 58 0E CD A1 CE 86 CD E8 C9 12 46 90
: }
523 9: SEQUENCE {
525 5: OBJECT IDENTIFIER sha1 (1 3 14 3 2 26)
532 0: NULL
: }
534 97: [0] {
536 24: SEQUENCE {
538 9: OBJECT IDENTIFIER contentType (1 2 840 113549 1 9 3)
549 11: SET {
551 9: OBJECT IDENTIFIER envelopedData (1 2 840 113549 1 7 3)
: }
: }
562 32: SEQUENCE {
564 10: OBJECT IDENTIFIER '1 2 840 113549 1 9 37 3'
576 18: SET {
578 16: OCTET STRING 85 D5 DA CC C2 97 B5 78 F7 60 52 9F 24 9B 45 74
: }
: }
596 35: SEQUENCE {
598 9: OBJECT IDENTIFIER messageDigest (1 2 840 113549 1 9 4)
609 22: SET {
611 20: OCTET STRING
: DD 89 06 A7 B4 56 A8 EC F1 DB 9F 69 BA 30 F6 5D
: CB 25 91 98
: }
: }
: }
633 13: SEQUENCE {
635 9: OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
646 0: NULL
: }
648 256: OCTET STRING
: 76 A2 36 CA 5B 8E 01 72 01 42 A7 1B 51 82 55 BD
: truncated ...
: }
: }
: }
: }
: }
最佳答案
这是一个封装EnvelopedCms消息的SignedCms消息(字节偏移量4)。
(字节偏移量43)。
该消息由序列号为40 01 58 68 58 0E CD A1 CE 86 CD E8 C9 12 46 90
的证书(字节偏移505)和颁发者“ CN = CA,O = ABC,C = US”(字节偏移460)签名。它使用RSA-SHA1(PKCS#1 v1.5填充)签名。
带符号的有效载荷(EnvelopedCms)使我感到困惑,因为字节偏移量443显示了一个位串,我不希望它出现(因此看不到应该在那个位置的数据)。我可以说的是,它是用一个目标接收者加密的,该目标接收者是颁发者“ CN = CA,O = ABC,C = US”(字节)的序列号为0A 01 41 7E 00 74 01 51 8F 8F 74 7E 8F 4D A6 B5
(字节偏移123)的证书的持有者偏移量78)。
-编辑:至于要求的字段:
字节偏移量648:这是来自签名者的RSA-PKCS1-SHA1签名。
字节偏移156:这是ktri.encryptedKey所在的位置。但这应该是OCTET STRING,而不是BIT STRING。这是AES / 3DES /任何密钥的RSA加密版本。
字节偏移578:应为编码的PKCS#9非结构化名称。但是从此解析输出来看似乎不合法。
奖金编辑:字节偏移443应该是一个以OID(0x06)开头的SEQUENCE(0x30),但这是一个具有6位未使用位字段的BIT STRING(0x03)。好像有人在某个地方向后有一个十六进制常量。
至于如何阅读...如果您使用.NET并使用C#:
SignedCms signedCms = new SignedCms();
signedCms.Decode(message);
// Throws on failure
signedCms.CheckSignature(true);
SignerInfoCollection signers = signedCms.SignerInfos;
if (signers.Count != 1 || signers[0].Certificate == null)
{
throw new InvalidOperationException("I don't know how to verify the signer trust");
}
// Exercise left to the reader
if (!IsSignerTrustedForThisMessage(signers[0].Certificate))
{
throw new CryptographicException();
}
EnvelopedCms envelopedCms = new EnvelopedCms();
envelopedCms.Decode(signedCms.ContentInfo.Content);
// If you know the expected certificate(s) for decryption
envelopedCms.Decrypt(candidateCertsWithPrivateKey);
// (which will search certificate stores if it can't find a match)
// otherwise `envelopedCms.Decrypt();` will -only- search the cert stores
// It's only the decrypted content after the call to Decrypt, of course.
byte[] decryptedMessage = envelopedCms.ContentInfo.Content;
对于Win32 C,您可能需要CryptMsg * API,而其他平台可能也有实现它的方法,而无需自己实现CMS RFC(IETF RFC 5652)。