我注意到,openssl x509 -in $FILE -text
有时会显示X.509 证书的序列号(一个最多 20 字节的正整数,因此最高有效位为 0),有时会显示为“八位字节字符串”,有时会显示为整数,后面跟着十六进制表示形式。
例如,这是“Letsencrypt”链中证书的序列号(16 字节序列号,但 MSB 为 1,有什么问题吗?):
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
91:2b:08:4a:cf:0c:18:a7:53:f6:d6:2e:25:a7:5f:5a
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, O=Internet Security Research Group, CN=ISRG Root X1
这是来自系统“证书包”的证书(8 字节序列号,MSB 为 0)
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 6828503384748696800 (0x5ec3b7a6437fa4e0)
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN=ACCVRAIZ1, OU=PKIACCV, O=ACCV, C=ES
来自同一捆绑包的另一个(16 字节序列号,MSB 为 0):
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
0c:e7:e0:e5:17:d8:46:fe:8f:e5:60:fc:1b:f0:30:39
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root CA
证书QuoVadis Root CA 2
(2字节序列号):
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1289 (0x509)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 2
这是一个具有 9 字节序列号的序列号(MSB 正确为 0):
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
11:00:34:b6:4e:c6:36:2d:36
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=RO, O=CERTSIGN SA, OU=certSIGN ROOT CA G2
另一个来自同一提供商的证书带有 6 字节序列号:
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 35210227249154 (0x200605167002)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=RO, O=certSIGN, OU=certSIGN ROOT CA
看起来有点随机。打印序列号有两种方式有什么特殊意义吗?
这只是打印序列号的风格选择。源代码
openssl x509 -text
中的逻辑是:-
在负数前加前导。(Negative)
负数。决定其大小的是序列号的绝对值:小序列号在 64 位系统上严格小于 2^63,在 32 位系统上严格小于 2^31(
sizeof(long)
这才是最重要的)。“序列号”实际上应该是一个八位字节字符串,因为它只是一个唯一标识符,从不用作数字。但它很久以前在 X.509 语法中被指定为整数,因此它被编码为整数。语法允许它是负整数,但语义禁止这样做。相反,语法阻止仅在前导零八位字节数上不同的序列号。
不完全是。RFC 5280含糊不清:它说“证书用户必须能够处理最多 20 个八位字节的 serialNumber 值”,但序列号是整数,而不是八位字节字符串,并且整数没有八位字节数。有两种合理的解释:
根据第二种解释, 20 个八位字节值的最高有效位必须为 0。例如,序列号在 (2^8)^16/2 和 (2^8)/16-1 之间是完全没问题的,就像 ISRG Root X1 签名的 Letsencrypt 证书中那样。
您可能误解了INTEGER 编码的限制,将其视为值的限制。在 INTEGER 编码中,第一个八位字节的最高位是符号位。这意味着序列号 0x912b084acf0c18a753f6d62e25a75f5a 被编码为
并不是
即 - 2^128 + 0x912b084acf0c18a753f6d62e25a75f5a = -0x6ed4f7b530f3e758ac0929d1da58a0a6。您可以使用 查看编码
openssl asn1 -dump …
。