S/MIME 签名和验证 - 我如何找到合适的证书?

信息安全 openssl x.509 微笑
2021-09-07 23:20:59

我正在尝试调试运行错误的 S/MIME 签名框架。在输入我有

  • 带有分离证书的签名消息
  • 可能使用哪个私钥签署消息的证书

但是当我试图把这一切放在一起时,我得到了

openssl smime -verify \
-in /tmp/efx5a9e37e3992a3/response.p7b -inform der \
-certfile /tmp/efx5a9e37e3992a3/equifax.pem -noverify \
-out /tmp/efx5a9e37e3992a3/response.xml

Verification failure
139699112142480:error:21FFF080:PKCS7routines:func(4095):
signer certificate not found:pkcs7/pk7_smime.c:470:

我知道这个错误可能是由于 openssl 实用程序清楚地看到我提议它用来验证消息的证书不是这个事实引起的。所以我的问题是 -我怎么能亲眼看到这个假设我可以从签名消息中转储 ASN.1 结构并像证书序列或它的指纹一样进行比较,我是否正确(发现这个信息突然显得有点棘手,所以我仍然不知道它是什么 - 可能是它其他一些属性)与我用于验证的证书 - 并亲自查看 - 好吧,是这样吗?

如果有人会指出我描述这个的文档,那也很好。

1个回答

###注意命名除了:您可能想说“单独”或“单独提供”或“未包含”证书。PKCS7/CMS/SMIME 中的“分离”与“嵌入”签名是一个相当重要的功能,尽管签名和证书是不同的东西,但很容易混淆。

#Hexdump 是的,您可以转储 PKCS7/CMS并查看标识签名者证书的信息,即颁发者名称和序列号或(很少,并且仅自 1999 年的 rfc2630 以来)密钥指纹(不是证书)。这是一个示例 der signeddata 不包含证书,但嵌入(不分离)数据(因为您的命令暗示了这一点)并使用签名属性(您没有指明一种或另一种方式):

$ xxd se181073.p7b
0000000: 3082 0262 0609 2a86 4886 f70d 0107 02a0  0..b..*.H.......
0000010: 8202 5330 8202 4f02 0101 310b 3009 0605  ..S0..O...1.0...
0000020: 2b0e 0302 1a05 0030 1706 092a 8648 86f7  +......0...*.H..
0000030: 0d01 0701 a00a 0408 666f 6f62 6172 0d0a  ........foobar..
0000040: 3182 0222 3082 021e 0201 0130 2030 1331  1.."0......0 0.1
0000050: 1130 0f06 0355 0403 0c08 7365 3138 3130  .0...U....se1810
0000060: 3733 0209 0083 2c1c 0d9b 0320 b930 0906  73....,.... .0..
0000070: 052b 0e03 021a 0500 a081 d830 1806 092a  .+.........0...*
0000080: 8648 86f7 0d01 0903 310b 0609 2a86 4886  .H......1...*.H.
0000090: f70d 0107 0130 1c06 092a 8648 86f7 0d01  .....0...*.H....
00000a0: 0905 310f 170d 3138 3033 3037 3036 3033  ..1...1803070603
00000b0: 3032 5a30 2306 092a 8648 86f7 0d01 0904  02Z0#..*.H......
00000c0: 3116 0414 60e6 44a5 6cb3 048e 15e6 2d88  1...`.D.l.....-.
00000d0: e311 c28e 5a4f 6d28 3079 0609 2a86 4886  ....ZOm(0y..*.H.
00000e0: f70d 0109 0f31 6c30 6a30 0b06 0960 8648  .....1l0j0...`.H
00000f0: 0165 0304 012a 300b 0609 6086 4801 6503  .e...*0...`.H.e.
0000100: 0401 1630 0b06 0960 8648 0165 0304 0102  ...0...`.H.e....
0000110: 300a 0608 2a86 4886 f70d 0307 300e 0608  0...*.H.....0...
0000120: 2a86 4886 f70d 0302 0202 0080 300d 0608  *.H.........0...
0000130: 2a86 4886 f70d 0302 0201 4030 0706 052b  *.H.......@0...+
0000140: 0e03 0207 300d 0608 2a86 4886 f70d 0302  ....0...*.H.....
0000150: 0201 2830 0d06 092a 8648 86f7 0d01 0101  ..(0...*.H......
0000160: 0500 0482 0100 0eea c31c bebb b64f 5c55  .............O\U
0000170: d5a5 5202 d59e 4742 57df cbce 42c9 f6b9  ..R...GBW...B...
0000180: 954a f6dd 1336 a99a be66 2513 bbba e176  .J...6...f%....v
0000190: acbd 2cf6 6988 847f 5fcd 6f28 e23f 1097  ..,.i..._.o(.?..
00001a0: 76a7 5f65 c028 25e2 c26d e054 d3a5 d7dc  v._e.(%..m.T....
00001b0: 5168 a71d 1860 b4e8 96fc e553 032d 3a03  Qh...`.....S.-:.
00001c0: 25cd 3761 3076 99a6 bf79 43ea 43a5 7438  %.7a0v...yC.C.t8
00001d0: d10b e160 dd66 f592 cea1 6ab7 221b 8ec1  ...`.f....j."...
00001e0: 9921 9ae1 f739 5b61 6495 290b 1f7f dae4  .!...9[ad.).....
00001f0: 41d5 0f9b 5acf 2331 1447 5755 a063 c7de  A...Z.#1.GWU.c..
0000200: 6830 ed43 875d a733 c588 370c e161 a7e8  h0.C.].3..7..a..
0000210: 005e 8afa c07b 5ade 2ffe dfb3 c0a0 1e28  .^...{Z./......(
0000220: 9726 5679 be4e d5ae 005c 8e50 ee83 13ac  .&Vy.N...\.P....
0000230: 1ea0 144c ad72 df79 d60b 9f5b 4f5f 188d  ...L.r.y...[O_..
0000240: f644 52cd 932b a24b b277 323c 7991 7418  .DR..+.K.w2<y.t.
0000250: 1bf8 c997 fd2f 1652 7658 ca42 be2f dc92  ...../.RvX.B./..
0000260: 678d 8dbd 756a                           g...uj

#asn1parse 现在用于asn1parse转储 ASN.1 结构和大部分内容:

$ openssl asn1parse -in se181073.p7b -inform der -i
    0:d=0  hl=4 l= 610 cons: SEQUENCE
    4:d=1  hl=2 l=   9 prim:  OBJECT            :pkcs7-signedData
   15:d=1  hl=4 l= 595 cons:  cont [ 0 ]
   19:d=2  hl=4 l= 591 cons:   SEQUENCE
   23:d=3  hl=2 l=   1 prim:    INTEGER           :01
   26:d=3  hl=2 l=  11 cons:    SET
   28:d=4  hl=2 l=   9 cons:     SEQUENCE
   30:d=5  hl=2 l=   5 prim:      OBJECT            :sha1
   37:d=5  hl=2 l=   0 prim:      NULL
   39:d=3  hl=2 l=  23 cons:    SEQUENCE
   41:d=4  hl=2 l=   9 prim:     OBJECT            :pkcs7-data
   52:d=4  hl=2 l=  10 cons:     cont [ 0 ]
   54:d=5  hl=2 l=   8 prim:      OCTET STRING      :foobar

   64:d=3  hl=4 l= 546 cons:    SET
   68:d=4  hl=4 l= 542 cons:     SEQUENCE
   72:d=5  hl=2 l=   1 prim:      INTEGER           :01
   75:d=5  hl=2 l=  32 cons:      SEQUENCE
   77:d=6  hl=2 l=  19 cons:       SEQUENCE
   79:d=7  hl=2 l=  17 cons:        SET
   81:d=8  hl=2 l=  15 cons:         SEQUENCE
   83:d=9  hl=2 l=   3 prim:          OBJECT            :commonName
   88:d=9  hl=2 l=   8 prim:          UTF8STRING        :se181073
   98:d=6  hl=2 l=   9 prim:       INTEGER           :832C1C0D9B0320B9
  109:d=5  hl=2 l=   9 cons:      SEQUENCE
  111:d=6  hl=2 l=   5 prim:       OBJECT            :sha1
  118:d=6  hl=2 l=   0 prim:       NULL
  120:d=5  hl=3 l= 216 cons:      cont [ 0 ]
  123:d=6  hl=2 l=  24 cons:       SEQUENCE
  125:d=7  hl=2 l=   9 prim:        OBJECT            :contentType
  136:d=7  hl=2 l=  11 cons:        SET
  138:d=8  hl=2 l=   9 prim:         OBJECT            :pkcs7-data
  149:d=6  hl=2 l=  28 cons:       SEQUENCE
  151:d=7  hl=2 l=   9 prim:        OBJECT            :signingTime
  162:d=7  hl=2 l=  15 cons:        SET
  164:d=8  hl=2 l=  13 prim:         UTCTIME           :180307060302Z
  179:d=6  hl=2 l=  35 cons:       SEQUENCE
  181:d=7  hl=2 l=   9 prim:        OBJECT            :messageDigest
  192:d=7  hl=2 l=  22 cons:        SET
  194:d=8  hl=2 l=  20 prim:         OCTET STRING      [HEX DUMP]:60E644A56CB3048E15E62D88E311C28E5A4F6D28
  216:d=6  hl=2 l= 121 cons:       SEQUENCE
  218:d=7  hl=2 l=   9 prim:        OBJECT            :S/MIME Capabilities
  229:d=7  hl=2 l= 108 cons:        SET
  231:d=8  hl=2 l= 106 cons:         SEQUENCE
  233:d=9  hl=2 l=  11 cons:          SEQUENCE
  235:d=10 hl=2 l=   9 prim:           OBJECT            :aes-256-cbc
  246:d=9  hl=2 l=  11 cons:          SEQUENCE
  248:d=10 hl=2 l=   9 prim:           OBJECT            :aes-192-cbc
  259:d=9  hl=2 l=  11 cons:          SEQUENCE
  261:d=10 hl=2 l=   9 prim:           OBJECT            :aes-128-cbc
  272:d=9  hl=2 l=  10 cons:          SEQUENCE
  274:d=10 hl=2 l=   8 prim:           OBJECT            :des-ede3-cbc
  284:d=9  hl=2 l=  14 cons:          SEQUENCE
  286:d=10 hl=2 l=   8 prim:           OBJECT            :rc2-cbc
  296:d=10 hl=2 l=   2 prim:           INTEGER           :80
  300:d=9  hl=2 l=  13 cons:          SEQUENCE
  302:d=10 hl=2 l=   8 prim:           OBJECT            :rc2-cbc
  312:d=10 hl=2 l=   1 prim:           INTEGER           :40
  315:d=9  hl=2 l=   7 cons:          SEQUENCE
  317:d=10 hl=2 l=   5 prim:           OBJECT            :des-cbc
  324:d=9  hl=2 l=  13 cons:          SEQUENCE
  326:d=10 hl=2 l=   8 prim:           OBJECT            :rc2-cbc
  336:d=10 hl=2 l=   1 prim:           INTEGER           :28
  339:d=5  hl=2 l=  13 cons:      SEQUENCE
  341:d=6  hl=2 l=   9 prim:       OBJECT            :rsaEncryption
  352:d=6  hl=2 l=   0 prim:       NULL
  354:d=5  hl=4 l= 256 prim:      OCTET STRING      [HEX DUMP]:0EEAC31CBEBBB64F5C55D5A55202D59E474257DFCBCE42C9F6B9954AF6DD1336A99ABE662513BBBAE176ACBD2CF66988847F5FCD6F28E23F109776A75F65C02825E2C26DE054D3A5D7DC5168A71D1860B4E896FCE553032D3A0325CD3761307699A6BF7943EA43A57438D10BE160DD66F592CEA16AB7221B8EC199219AE1F7395B616495290B1F7FDAE441D50F9B5ACF233114475755A063C7DE6830ED43875DA733C588370CE161A7E8005E8AFAC07B5ADE2FFEDFB3C0A01E2897265679BE4ED5AE005C8E50EE8313AC1EA0144CAD72DF79D60B9F5B4F5F188DF64452CD932BA24BB277323C799174181BF8C997FD2F16527658CA42BE2FDC92678D8DBD756A
 $ # -i causes the output 'details' to be indented according to the structure; 
 $ # you can omit this and just use the d=depth values but that's slightly harder

#SignerInfo 结构 将此与 PKCS7 或其更新、更方便的 IETF 化形式 Cryptographic Message Syntax CMS rfc2315 section 9rfc2360 section 5.1rfc3369 dittorfc3852 ditto指定的结构进行比较。首先有一个外部包装器(在上述参考文献的第 7 节或第 3 节中定义),它是一个 OID 和一个 context-0 标记的 SEQUENCE,对于签名数据来说,它是一个 SEQUENCE。在偏移量 23 处我们有版本号,在 26 处是摘要 AlgId 集,在 39 处是包含数据的 EncapsulatedContentInfo。由于(所有)证书被省略,在偏移量 64 处,我们有 SignerInfo 的 SET,稍后在 9.2 或 5.3 节中定义了几页:

SignerInfo ::= SEQUENCE {
        version CMSVersion,
        sid SignerIdentifier,
        digestAlgorithm DigestAlgorithmIdentifier,
        signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
        signatureAlgorithm SignatureAlgorithmIdentifier,
        signature SignatureValue,
        unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL }

SignerIdentifier ::= CHOICE {
        issuerAndSerialNumber IssuerAndSerialNumber,
        subjectKeyIdentifier [0] SubjectKeyIdentifier }

-- SubjectKeyIdentifier is defined elsewhere as OCTET STRING

SignatureValue ::= OCTET STRING

因此,在偏移量 72 处,我们有 SI 的版本,在 77 处,发行者名称是通常几个 SET 的序列(在我的简单示例中只有一个,CommonName),每个集合包含一个或多个(这里是一个)对(SEQUENCE)的 OID 和值,在 98 处是序列号这些匹配(并取自)证书中的颁发者名称和序列号。对于其他签名软件,我们可以改为使用包含 OCTET STRING 的 context-0 标记,该标记匹配(并取自)证书中的 SubjectKeyIdentifier 扩展名(如果存在)。

最后,在偏移量 102 我们有摘要的 AlgId,在 120 context-0 包含签名属性(以前称为已验证),这是 OID 和值 SET 对(SEQUENCE)的隐式序列,在 339签名本身作为 AlgId 和 OCTET STRING。

如果您不知道,我将其缩写为 AlgId 的 AlgorithmIdentifier 由 X.509(以及因此 rfc3280 和 rfc5280)定义为算法的 OID 的序列加上该算法的不同类型的“参数”——对于我使用的算法,RSA,参数为NULL。这种配对在加密货币中使用非常广泛。请注意,分配给 rsaEncryption 的 OID 也用于 RSA 签名,尽管 1970 年代最初的“签名是用私钥加密”的概念被证明具有危险的误导性并被丢弃;security.SX 和 crypto.SX 对此有很多答案和评论。

#Successful verification 下面是使用该证书成功验证的演示:

$ openssl x509 -issuer -serial -subject -in se181073.cer
issuer= /CN=se181073
serial=832C1C0D9B0320B9
subject= /CN=se181073
-----BEGIN CERTIFICATE-----
MIIC+TCCAeGgAwIBAgIJAIMsHA2bAyC5MA0GCSqGSIb3DQEBBQUAMBMxETAPBgNV
BAMMCHNlMTgxMDczMB4XDTE4MDMwNzA1NTk1NloXDTE4MDQwNjA1NTk1NlowEzER
MA8GA1UEAwwIc2UxODEwNzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQDG2pTlbFNwDnlrdY7FvncTzVyQt5xkb7fYqnqPtD3HxH8u7lcxZ9KwhOPjwvgU
+axwhELXYBuzgKRDwTWoEqM7UfeGh5HSLlGiG12R8oiSJ9h/iQt5clVbNm3seaof
MzdutbOhINKJ31daZMu3MQpf49Ebj1itzudGfi4lzYcaK+Y7eCymc0LPi0CIvWzK
TUVaFA7/VqVzakUB/+ocuIWZ+OBW4/6q0ZiR0CdsAuA/POCsdqM3KfA+hoI2D0Oo
omi5uU3+h6DmUZbkcutESEDKnKNlRuThQ7AVGHG62Gkz47m+E7miq6jRz55Ls+vn
DfjAKsBChKALE3hND0vS51ghAgMBAAGjUDBOMB0GA1UdDgQWBBTX5DUE4YccOajN
0HSvLQeUND0dLzAfBgNVHSMEGDAWgBTX5DUE4YccOajN0HSvLQeUND0dLzAMBgNV
HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCasepCDDCmsoGfUj8ixP56AeSe
caqxtrm67weKGwEJQiVbMUkvWtrMHoySGlWFymzy/GKvrpuW+7TuyrYcu8JqO6gK
MaxhLSum5peJlE9H8HZNhaznjTwj2Vl9tDCP0WN0e+9z/4oPlE7x3GLtUoELcWvj
trrIVYYvX5hO62EDeKNpW6EbY33KuabsudEc5VV1a1dPnAnI5bbSNEoE2RKBvQ6V
f3MWzarGIDC0Pe1Q6TmAuCcXnz9OXclPD7TGqOCB6YwrQFOWe/9fV69k/D5TsFyz
SH4U9V9adNyY1T67Ib5EYFMbUXU4FAAwj0SIPjGjGvkehoNRojMZuWlA0pnX
-----END CERTIFICATE-----
$ openssl smime -verify -in se181073.p7b -inform der -certfile se181073.cer -noverify
foobar
Verification successful