openssl 忽略序列号扩展

openssl ignores Serial number extension

美好的一天! 我创建了一个证书请求,结果如下:

-----BEGIN CERTIFICATE REQUEST-----
MIICszCCAZsCAQAwKzEKMAgGA1UEChMBczEQMA4GA1UECxMHb3JnVW5pdDELMAkG
A1UEAxMCY24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC4p/WHGkLZ
DGuUenb8e+FtwimfPQvAGJU4IwVKgjjk3cqqdED2PgyeSKQEehyWdnEaGaKdDQ72
unsPfOeRYAbzhEeKNM0qH/jx5gC5CO0/lq58UQOtBg4GXMLCMel+QIofBb1UGbLo
KviHLR02jfqYrUf72GY83JrhUGlzAJEl6upDvuZalp5qXql9ge8ylfGx/iOUYPk7
/gvfTOLDQmDKcUQ9nW8H9U+cl82lcsBMv7V4XCoG16GfEIziLyFHtLwvAwvGE2md
IEnoMwhY0cUxp/c8bzL0hvNvMDy1lNBJ14wohdTh95/Guf46d8DtWc7e1Nrb+biT
HxWsftA4WEQdAgMBAAGgQzBBBgkqhkiG9w0BCQ4xNDAyMDAGA1UEBQQpVURJRDow
MDAwMDAwMC03YTBlLTkyNTUtZmZmZi1mZmZmYmY4ZmYyZDUwDQYJKoZIhvcNAQEL
BQADggEBAEm8HXmmxZ7B6Omcezuhle1Xz/9Iiaet2SnkSwm0dVmZXzyamWFHSls+
1biMtZb3Ath0TeDQ7kUh40SyFBKOTSWD8EhbgsMrys0ALUOJ16r2mGXbVdnoc/52
dm8jKXSqB/tKa4AXDQJkR6GNJtNu3k4XHSz25felkZosqGHdPmnQGiPDpJsFenxm
yD+nYTUrzrMM4FrBKLDex4mT0raFEkxN52wIwQ+UtI84OfxebztKSr+WCeafCKnV
idQrTBcM5zMdAPSgKIdh2kFOr3WdXgLonQiQ8GVleBdFGy0aw1LRVZ3+XsIrnEx2
L1dRm4u70iXtUwYw5tSaK6KNT7SJo00=
-----END CERTIFICATE REQUEST-----

两个词 - 它说:

cn
Certificate request

Public Key Info
Key Algorithm:  RSA
Key Parameters: 05 00
Key Size:   2048
Key SHA1 Fingerprint:   E4 .. E9 49 A3 D3

Public Key: 30 82 01 0A 02 82 01 01 ... 03 01 00 01

现在最重要的是:

Extension
Identifier: Serial Number
Value:  55 44 49 44 3A 30 30 30 30 30 30 30 30 2D 37 61 30 65 2D 39 32     35 35 2D 66 66 66 66 2D 66 66 66 66 62 66 38 66 66 32 64 35
Critical:   No

我希望这个扩展序列号出现在我未来的证书中。 但是当我做类似

的事情时
openssl x509 -req -in ../req.req -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out user.crt -days 5000 -extensions v3_usr -CAcreateserial

我没有得到我的扩展结果 user.cer。我做错了什么?

您使用 -CAcreateserial 选项。它记录为:

-CAcreateserial

with this option the CA serial number file is created if it does not exist: it will contain the serial number "02" and the certificate being signed will have the 1 as its serial number. If the -CA option is specified and the serial number file does not exist a random number is generated; this is the recommended practice.

要明确设置序列号,您可能需要使用选项 -CAserial

-CAserial filename

sets the CA serial number file to use.

When the -CA option is used to sign a certificate it uses a serial number specified in a file. This file consist of one line containing an even number of hex digits with the serial number to use. After each use the serial number is incremented and written out to the file again.

The default filename consists of the CA certificate file base name with ".srl" appended. For example if the CA certificate file is called "mycacert.pem" it expects to find a serial number file called "mycacert.srl".

只需将所需的序列号写入文件并使用即可。

我怀疑有几个问题。

首先,您的扩展值格式不正确。它缺少 extnValue 字段的嵌套 ASN.1 类型标识符。根据 RFC5280,X.509 扩展名是:

Extension  ::=  SEQUENCE  {
     extnID      OBJECT IDENTIFIER,
     critical    BOOLEAN DEFAULT FALSE,
     extnValue   OCTET STRING
                 -- contains the DER encoding of an ASN.1 value
                 -- corresponding to the extension type identified
                 -- by extnID
     }

extnValue(即 OCTET_STRING)下,您应该放置嵌套类型(我不知道序列号扩展名的确切语法)。它可以是 SEQUENCE、另一个 OCTET_STRING 或 INTEGER(因为序列号是整数)。

但是,您的嵌套类型丢失了: 在选中的 OCTET_STRING 下应该还有另一个嵌套节点,而您将序列号直接放置为 extnValue payload.

如果此扩展旨在指示 CA 在证书中放置指定的序列号(作为 FIELD),那么您违反了另一个要求:

§4.1.2.2

Certificate users MUST be able to handle serialNumber values up to 20 octets. Conforming CAs MUST NOT use serialNumber values longer than 20 octets.

您的序列号看起来比 20 个八位字节长一点。此外,您可能会违反本节的第一部分:

It MUST be unique for each certificate issued by a given CA (i.e., the issuer name and serial number identify a unique certificate).

也就是说,如果用户要求提供特定的序列号,可能会导致序列号不唯一。

编辑: 根据 Ilya Matveychikov 的说法,嵌套类型应为 PrintableString。这意味着您的扩展值应该是:

13 2B 55 44 49 44 3A 30  30 30 30 30 30 30 30 2D
37 61 30 65 2D 39 32 35  35 2D 66 66 66 66 2D 66
66 66 66 62 66 38 66 66  32 64 35

编码后,它将如下所示:

按照OID 2.5.4.5的定义,必须有PrintableString放在extnValue上:

serialNumber ATTRIBUTE ::= {
    WITH SYNTAX PrintableString (SIZE (1..ub-serialNumber))
    EQUALITY MATCHING RULE caseIgnoreMatch
    SUBSTRINGS MATCHING RULE caseIgnoreSubstringsMatch
    ID id-at-serialNumber
}