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

时间:2018-06-14 14:59:09

标签: c# .net cryptography 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 ...
       :           }
       :         }
       :       }
       :     }
       :   }

1 个答案:

答案 0 :(得分:4)

这是包装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显示了一个BIT STRING,我不指望它(因此看不到应该在该位置的数据)。我能说的是,它是由一个目标收件人加密的,该收件人是发行人“CN = CA,O = ABC,C = US”的序列号为0A 01 41 7E 00 74 01 51 8F 8F 74 7E 8F 4D A6 B5(字节偏移123)的证书的持有者。 (字节偏移78)。

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

  • byte offset 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)。