How to get the certificate ID / fingerprint of an x.509 certificate using node-forge?
Update
I need this for AWS IoT. I've been investigating and ended up that AWS probably uses some fingerprint algorithm to extract the certificate ID. It is not baked into the cert, probably the public key is used as a base for the fingerprint.
Update 2
Running this mand returns the correct fingerprint: openssl x509 -noout -fingerprint -sha256 -inform pem -in cert.crt
How to achieve this with node-forge?
I've put together the following one but it does not return the same fp.:
const fs = require('fs')
const forge = require('node-forge')
const { pki } = forge
const { promisify } = require('es6-promisify')
const readFile = promisify(fs.readFile)
async function main() {
const certPem = await readFile('./cert.crt', 'utf-8')
const cert = pki.certificateFromPem(certPem)
const fingerprint = pki.getPublicKeyFingerprint(cert.publicKey, {
md: forge.md.sha256.create(),
encoding: 'hex',
})
}
main()
How to get the certificate ID / fingerprint of an x.509 certificate using node-forge?
Update
I need this for AWS IoT. I've been investigating and ended up that AWS probably uses some fingerprint algorithm to extract the certificate ID. It is not baked into the cert, probably the public key is used as a base for the fingerprint.
Update 2
Running this mand returns the correct fingerprint: openssl x509 -noout -fingerprint -sha256 -inform pem -in cert.crt
How to achieve this with node-forge?
I've put together the following one but it does not return the same fp.:
const fs = require('fs')
const forge = require('node-forge')
const { pki } = forge
const { promisify } = require('es6-promisify')
const readFile = promisify(fs.readFile)
async function main() {
const certPem = await readFile('./cert.crt', 'utf-8')
const cert = pki.certificateFromPem(certPem)
const fingerprint = pki.getPublicKeyFingerprint(cert.publicKey, {
md: forge.md.sha256.create(),
encoding: 'hex',
})
}
main()
Share
Improve this question
edited Jul 10, 2018 at 8:23
haxpanel
asked Jul 9, 2018 at 19:24
haxpanelhaxpanel
4,6785 gold badges49 silver badges75 bronze badges
9
- Which problem you have? – pedrofb Commented Jul 9, 2018 at 19:49
- I'm creating x509 certificates for devices and want to assign these to users. – haxpanel Commented Jul 10, 2018 at 6:48
- Actually I need the same certificate ID that AWS uses. – haxpanel Commented Jul 10, 2018 at 7:16
- I think that's an sha256 fingerprint... But for some reason I can't get the same one AWS extracts when I upload the cert. – haxpanel Commented Jul 10, 2018 at 7:44
- You may want to include this information in your question so that it can be answered: The algorithm used by AWS to determine the "ID" and the code you are using – pedrofb Commented Jul 10, 2018 at 7:49
3 Answers
Reset to default 6To expand on the solution of haxpanel with some code in your requested NodeJS code:
const crypto = require("crypto");
function getCertificateFingerprint(certString) {
const baseString = certString.match(/-----BEGIN CERTIFICATE-----\s*([\s\S]+?)\s*-----END CERTIFICATE-----/i);
const rawCert = Buffer.from(baseString[1], "base64");
const sha256sum = crypto.createHash("sha256").update(rawCert).digest("hex");
return sha256sum.toUpperCase().replace(/(.{2})(?!$)/g, "$1:");
// eg 83:6E:3E:99:58:44:AE:61:72:55:AD:C6:24:BE:5C:2D:46:21:BA:BE:87:E4:3A:38:C8:E8:09:AC:22:48:46:20
}
here you are. The result will same as openssl x509 -in a.pem -fingerprint -sha256 -noout
import forge from 'node-forge'
fingerprint() {
const der = forge.asn1.toDer(forge.pki.certificateToAsn1(cert)).getBytes()
const m = forge.md.sha256.create().start().update(der)
return m.digest()
.toHex()
.match(/.{2}/g)
.join(':')
.toUpperCase()
}
The solution is:
You just need to extract the string from between the "-----BEGIN CERTIFICATE-----" header and "-----END CERTIFICATE----- " footer, base64 decode it and pute SHA1 hash of decoded data.
In this case SHA256.