为什么 CertificateRequest.Create 有时会在序列号中添加前导零字节?

Why does CertificateRequest.Create add a leading zero byte to the serial number sometimes?

示例:

//generate specific serial number for testing purposes
byte[] result = "A0-41-A1-32-BD-9E-58-98-4B-CC-9E-E6-27-17-B4-10"
   .Split('-')
   .Select(item => Convert.ToByte(item, 16))
   .ToArray();

using (X509Certificate2 cert = certRequest.Create(
        caCert,
        DateTimeOffset.UtcNow.AddDays(-1),
        DateTimeOffset.UtcNow.AddYears(50),
        serialNumber))
    {
        // display serial number for testing purposes
        Console.WriteLine(cert.SerialNumber);
    }

输入序列号:"A0-41-A1-32-BD-9E-58-98-4B-CC-9E-E6-27-17-B4-10"

证书实际序列号:"00-A0-41-A1-32-BD-9E-58-98-4B-CC-9E-E6-27-17 -B4-10

预期序列号与输入相同,没有前导零字节。

方法文档:https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.certificaterequest.create?view=netframework-4.7.2

https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.2

The serial number MUST be a positive integer assigned by the CA to each certificate. It MUST be unique for each certificate issued by a given CA (i.e., the issuer name and serial number identify a unique certificate). CAs MUST force the serialNumber to be a non-negative integer. ...

(强调我的)

序列号存储为 DER 整数,这是最小字节数的带符号大端值。

  • {0x79} 为正数
  • { 0x80 } 为负数
  • { 0x00, 0x80 } 为正数

如果你给它一个值 serialNumber[0] > 0 && serialNumber[0] < 0x80 那么字节将保持原样。

如果你给它一个值,其中 serialNumber[0] == 0 && serialNumber[1] < 0x79 然后前导字节被删除(重复直到你达到值 { 0x00 } 或需要零的点)。

这两个语句(略斜)嵌入The value is interpreted as an unsigned integer of arbitrary size in big-endian byte ordering.

为了拟人化该方法,它说“我被赋予了这个大值,0xA041A132BD9E58984BCC9EE62717B410,我知道它是一个大的正数。现在我需要将它记为 DER 整数。等效字节流 { 0x00, 0xA0, 0x41, 0xA1, 0x32, 0xBD, 0x9E, 0x58, 0x98, 0x4B, 0xCC, 0x9E, 0xE6, 0x27, 0x17, 0xB4, 0x10 }。完成。“