解码 ASN.1 - PKCS#7 非分离签名



我对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 ...
:           }
:         }
:       }
:     }
:   }

它是一个SignedCms消息(字节偏移量4(,包装了一个EnvelopedCms消息。 (字节偏移量 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 显示了一个我不希望的 BIT 字符串(因此看不到应该在该位置的数据(。 我能说的是,它是使用单个目标收件人加密的,该收件人是来自颁发者"CN=CA,O=ABC,C=US"(字节偏移量 78(的序列号为0A 01 41 7E 00 74 01 51 8F 8F 74 7E 8F 4D A6 B5(字节偏移量 123(的证书的持有者。

--编辑:至于请求的字段:

  • 字节偏移量 648:这是签名者的 RSA-PKCS1-SHA1 签名。
  • 字节偏移量 156:这是 ktri.encryptedKey 应该在的地方。 但这应该是一个八位字节字符串,而不是一个位字符串。 这是 AES/3DES/任何密钥的 RSA 加密版本。
  • 字节偏移量 578:这应该是编码的 PKCS#9 非结构化名称。 但从这个解析输出来看,这似乎不合法。

额外编辑:字节偏移量 443 应该是以 OID (0x06( 开头的序列 (0x30(,但它是一个具有 6 位未使用位字段的位字符串 (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( 即可做到这一点。

最新更新