forge icon indicating copy to clipboard operation
forge copied to clipboard

How to return binary encoded p12 file without encoding it using base64

Open snehalchaudhari98 opened this issue 2 years ago • 2 comments

I'm able to generate a p12 file using all certificates and keys by following steps mentioned in https://github.com/digitalbazaar/forge#pkcs12 here. Just on server side user first need to decode this certificate while extracting certs and keys using openssl. I want to skip this step, so I don't want to encode the certificate in base64 in last mentioned steps:

**Actual**
// base64-encode p12
var p12Der = forge.asn1.toDer(p12Asn1).getBytes();
var p12b64 = forge.util.encode64(p12Der);
return p12b64 ;

**Modified**
// base64-encode p12
var p12Der = forge.asn1.toDer(p12Asn1).getBytes();
return p12Der ;

But if I create p12 file using modified changes and then try to extract the certs and keys in that file using openssl, I'm getting following error -
4145202984:error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long:asn1_lib.c:157:

It was initially working as expected when I was encoding p12 content in base64. But At that time there was just a overhead to decode given p12 file before extracting any cert or key. How can I skip this encoding process and achieve the required result?

I'm a bit new to this so just a follow-up question. Why in the first place we need to perform base64 encoding on p12? Would really appreciate any advise on this.

snehalchaudhari98 avatar Mar 01 '22 12:03 snehalchaudhari98

I've got the exact question. Looking forward to responses

nayanramnanan avatar Mar 01 '22 23:03 nayanramnanan

The reason for the base64 conversion is to make it downloadable in the browser using Data URLs.

If you need a binary .p12/.pfx file in node, the following should work:

const p12Asn1 = forge.pkcs12.toPkcs12Asn1(
    keyPair.privateKey,
    certificate,
    'password',
    {
        algorithm: '3des', // Triple DES to attain maximum compatibility with PKCS parsers
        generateLocalKeyId: true, // true is the default but it does not hurt to specify it anyway
    },
)
const p12Der = forge.asn1.toDer(p12Asn1).getBytes()

await fs.promises.writeFile('cert.p12', p12Der, {encoding: 'binary'})

You can verify the p12 file using openssl pkcs12 -in certificate.p12 -info.

if you need to make it downloadable in the browser, you can add:

const p12b64 = forge.util.encode64(p12Der)

const a = document.createElement('a')
a.download = 'certificate.p12'
a.setAttribute('href', `data:application/x-pkcs12;base64,${p12b64}`)
a.appendChild(document.createTextNode('Download certificate.p12'))
document.body.appendChild(a)

MatthiasKunnen avatar Mar 09 '22 18:03 MatthiasKunnen