Search code examples
javascriptx509certificate2pfxpkcs#12

How to get X509Certificate thumbprint in Javascript?


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!


Solution

  • 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();