I need to write a function in javascript (forge) that get a thumbnail of a pfx certificate. I created a test certificate(mypfx.pfx). By using c# X509Certificate2 library, I can see thumbprint of input certificate in X509Certificate2 object by passing file bytes array and password. Here is c# code snippet:
X509Certificate2 certificate = new X509Certificate2(byteArrayCertData, password);
var thumbprint = certificate.Thumbprint;
//thumbprint is a hex encoding SHA-1 hash
But when I am trying to do the same thing in javascript (using forge). I can't get a correct thumbprint. Here is my Javascript code:
var certi = fs.readFileSync('c:/mypfx.pfx');
let p12b64 = Buffer(certi).toString('base64');
let p12Der = forge.util.decode64(p12b64);
var outAsn1 = forge.asn1.fromDer(p12Der);
var pkcs12 = forge.pkcs12.pkcs12FromAsn1(outAsn1, false, "1234");
var fp = null;
for (var sci = 0; sci < pkcs12.safeContents.length; ++sci) {
var safeContents = pkcs12.safeContents[sci];
for (var sbi = 0; sbi < safeContents.safeBags.length; ++sbi) {
var safeBag = safeContents.safeBags[sbi];
if (safeBag.cert != undefined && safeBag.cert.publicKey != undefined) {
fp = forge.pki.getPublicKeyFingerprint(safeBag.cert.publicKey, {type: 'RSAPublicKey'});
//Is this fingerprint value I am looking for??
break;
}
}
}
The result is different value compare to c# thumbprint which seems to be wrong. I tried different functions in pkcs12.js file. None of them works. It's acceptable using other JS library as long as correct thumbprint result is produced. Please help and correct any mistakes I made. Thanks!
You are comparing different data. The certificate thumbprint is not the same that the public key fingerprint.
The certificate thumbprint is a hash calculated on the entire certificate. Seems forge does not have a method, but you can calculate yourself
//SHA-1 on certificate binary data
var md = forge.md.sha1.create();
md.start();
md.update(certDer);
var digest = md.digest();
//print as HEX
var hex = digest.toHex();
console.log(hex);
To convert the forge certificate to DER (binary) you can use this
var certAsn1 = forge.pki.certificateToAsn1(cert);
var certDer = forge.asn1.toDer(certAsn1).getBytes();