Percebi que openssl x509 -in $FILE -text
às vezes exibe o número de série de um certificado X.509 (um número inteiro positivo de até 20 bytes, portanto o bit mais significativo em 0), às vezes como uma "string de octetos" e às vezes como um número inteiro com sua representação hexadecimal a seguir.
Por exemplo, aqui está o número de série de um certificado na cadeia "Letsencrypt" (número de série de 16 bytes, mas o MSB é 1, algo está errado?):
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
Aqui está um certificado do "pacote de certificados" do sistema (número de série de 8 bytes, MSB é 0)
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 6828503384748696800 (0x5ec3b7a6437fa4e0)
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN=ACCVRAIZ1, OU=PKIACCV, O=ACCV, C=ES
Outro do mesmo pacote (número de série de 16 bytes, 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
O certificado QuoVadis Root CA 2
(número de série de 2 bytes):
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1289 (0x509)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 2
Aqui está um com número de série de 9 bytes (MSB corretamente em 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
E um do mesmo provedor, um certificado com número de série de 6 bytes:
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 35210227249154 (0x200605167002)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=RO, O=certSIGN, OU=certSIGN ROOT CA
Parece bastante aleatório. Existe um significado particular em haver duas maneiras de imprimir o número de série?
É apenas uma escolha estilística na forma como
openssl x509 -text
os números de série são impressos. A lógica no código-fonte é:-
para números negativos.(Negative)
para números negativos.O que determina pequeno versus grande é o valor absoluto do número de série: um número de série pequeno é estritamente menor que 2 ^ 63 em um sistema de 64 bits ou 2 ^ 31 em um sistema de 32 bits (
sizeof(long)
sendo o que importa).O “número de série” deveria realmente ser uma string de octeto, já que é apenas um identificador único e nunca é usado como um número. Mas foi especificado como um número inteiro na sintaxe X.509 há muito tempo, portanto é codificado como um número inteiro. A sintaxe permite que seja um número inteiro negativo, mas a semântica proíbe isso. Por outro lado, a sintaxe evita números de série que diferem apenas no número de zero octetos iniciais.
Não exatamente. RFC 5280 é ambíguo: diz “Usuários de certificados DEVEM ser capazes de lidar com valores serialNumber de até 20 octetos”, mas um número de série é um INTEGER, não uma OCTET STRING, e um INTEGER não possui uma contagem de octetos. Existem duas interpretações plausíveis:
De acordo com a segunda interpretação, o bit mais significativo do valor de 20 octetos deve ser 0. É perfeitamente normal ter, por exemplo, um número de série entre (2^8)^16/2 e (2^8)/16- 1, como no certificado Letsencrypt assinado por ISRG Root X1.
Você provavelmente está interpretando mal as restrições nas codificações de um INTEGER como restrições no valor. Na codificação de um INTEGER, o bit superior do primeiro octeto é um bit de sinal. Isso significa que o número de série 0x912b084acf0c18a753f6d62e25a75f5a é codificado como
e não
que seria - 2 ^ 128 + 0x912b084acf0c18a753f6d62e25a75f5a = -0x6ed4f7b530f3e758ac0929d1da58a0a6. Você pode ver a codificação com
openssl asn1 -dump …
.