Mr.D Mr.D - 11 days ago 6
Javascript Question

Node JS, how to extract X.509 Certificate from P12 file?

I have

p12
file, where I should get X.509 Certificate. In order to work with this file I use
forge
library:

var forge = require('node-forge');
var fs = require('fs');

var keyFile = fs.readFileSync("/path/to/p12/file.p12", 'binary');
var p12Asn1 = forge.asn1.fromDer(keyFile);

var p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, 'password');

var bags = p12.getBags({bagType: forge.pki.oids.certBag});

var cert = bags[forge.pki.oids.certBag][0];

console.log(cert);


Console outputs to me this kind of information:

{ type: '1.2.840.113549.1.12.10.1.3',
attributes:
{ localKeyId: [ 'aoa ??xx\u0015-?]%m§ §\f,\u0013' ],
friendlyName: [ 'e56fe5a0899f787815adaf5d256da7a0a70c2c13' ] },
cert: null,
asn1:
{ tagClass: 0,
type: 16,
constructed: true,
composed: true,
value: [ [Object], [Object], [Object] ] } }


This result means that I have an alias with name
e56fe5a0899f787815adaf5d256da7a0a70c2c13
, but why
cert
is
null
?

There is Java's security api's, which is able to extract X.509 certificate from this p12 file by it's alias.

X509Certificate x509Certificate = (X509Certificate) ks.getCertificate(alias);


How it is possible to extract X.509 certificate from
p12
file by using
forge
?

Node version
5.4.1


Forge Version
0.6.45


There you can download my testing p12 file: link

password is
123456

Answer

According to [https://github.com/digitalbazaar/forge/issues/237#issuecomment-93555599]:

If forge doesn't recognize the key format, it will return null for the key property in the key bag, and set an asn1 property with the raw ASN.1 representation of the key.

So, you need convert to ASN.1, then DER, then PEM-encode:

var forge = require('node-forge');
var fs = require('fs');

var keyFile = fs.readFileSync("./gost.p12", 'binary');
var p12Asn1 = forge.asn1.fromDer(keyFile);

var p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, '123456');

var bags = p12.getBags({bagType: forge.pki.oids.certBag});

var bag = bags[forge.pki.oids.certBag][0];

// convert to ASN.1, then DER, then PEM-encode
var msg = {
  type: 'CERTIFICATE',
  body: forge.asn1.toDer(bag.asn1).getBytes()
};
var pem = forge.pem.encode(msg);

console.log(pem);