Hello,
The initial "00" does not appear to be significant and is not implemented on the standard node:crypto X509Certificate when we get the serial number.
Source:
https://stackoverflow.com/questions/45821143/ssl-certificates-leading-zeros-are-displayed-in-windows-but-not-unix-ksh-shell
https://openssl-users.openssl.narkive.com/Pds1yxYr/leading-zeros-in-serial-numbers#
How to reproduce this issue :
Generate a random 12-bytes serial number
openssl rand -hex 12
87d2fc16d9e738998f1f92c1
Convert it as integer
BigInt('0x87d2fc16d9e738998f1f92c1')
42035541205884290034770612929n
Create a certificate with the following openssl command:
openssl req -x509 -new -newkey rsa:2048 -days 365 -nodes -keyout key.pem -out cert.crt -set_serial 42035541205884290034770612929
Then on node:
import crypto from 'node:crypto';
import fs from 'node:fs';
const pem = fs.readFileSync('cert.crt', 'utf8').toString();
const certificate = new crypto.X509Certificate(pem);
console.log(certificate);
Result:
X509Certificate {
subject: 'C=AU\nST=Some-State\nO=Internet Widgits Pty Ltd',
subjectAltName: undefined,
issuer: 'C=AU\nST=Some-State\nO=Internet Widgits Pty Ltd',
infoAccess: undefined,
validFrom: 'Jul 25 11:43:39 2024 GMT',
validTo: 'Jul 25 11:43:39 2025 GMT',
fingerprint: 'D4:C3:55:4C:33:11:9F:0D:93:29:3F:C0:B3:C5:D1:D6:EF:A9:7D:A7',
fingerprint256: '36:35:19:84:3F:22:05:6D:73:6E:FB:A9:6A:60:C0:74:09:4E:7D:35:4A:9B:F0:E6:9A:9B:8D:BE:0B:BB:82:BF',
fingerprint512: 'E1:40:0B:6F:E6:34:73:8C:85:C2:F8:F7:02:0E:93:74:AA:EE:7F:45:F1:6E:DF:C2:A1:50:38:39:83:C3:20:A3:69:82:B7:F0:43:AE:44:24:9F:EF:BF:BD:2C:F5:DC:33:6E:B3:AE:82:B6:BF
:1F:8E:EA:E0:32:66:1F:49:15:97',
keyUsage: undefined,
serialNumber: '87D2FC16D9E738998F1F92C1'
}
Now with this code:
import fs from 'node:fs';
import asn1 from 'asn1js';
import pkijs from 'pkijs';
import pvutils from 'pvutils';
const pem = fs.readFileSync('cert.crt', 'utf8').toString();
const b64 = pem.replace(/(-----(BEGIN|END) CERTIFICATE-----|[\n\r])/g, '')
const der = Buffer.from(b64, 'base64')
const ber = Buffer.from(new Uint8Array(der))
const asn1Cert = asn1.fromBER(ber)
const certificate = new pkijs.Certificate({ schema: asn1Cert.result })
const serialNumber = pvutils.bufferToHexCodes(certificate.serialNumber.valueBlock.valueHexView)
console.log('serialNumber', serialNumber);
Result:
serialNumber 0087D2FC16D9E738998F1F92C1
Check with openssl
openssl x509 -in cert.crt -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
87:d2:fc:16:d9:e7:38:99:8f:1f:92:c1
Signature Algorithm: sha256WithRSAEncryption
Could you fix the bufferToHexCodes method to not return the initial "00" if they are not needed ?