Reputation: 328
I'm trying to create an encryption PHP-OPENSSL module to sign data and communicate with a third-party app. I have a digital .PFX certificate (cert.pfx) for this purpose.
I can open it and read it with openssl_pkcs12_read() with my passphrase.
The setup of the third party app ask me to upload the .cer public key of my certificate.
Because, i only have a .pfx file. I'm trying to extract the .cer public key from the PFX to create and upload the .cer file.
I'm using PHP-OPENSSL.
I tried to do it with this command :
$pkeydet = openssl_pkey_get_details(openssl_pkey_get_public(file_get_contents("/path/to/cert.pfx")));
But it doesn't give the expected result (openssl_pkey_get_details() expects parameter 1 to be resource, boolean given). I'm not sure the reason why...
What this the correct way to achieve the creation of the .cer file?
Thank you :)
Upvotes: 0
Views: 1105
Reputation: 328
I think i found the solution, I need to make a conversion from PFX to PEM to CER because the function openssl_pkey_get_details() only works with a .pem certificate.
Here is what I did :
$pass = "thisismypass"; // my pfx is pwd protected
$cert_info = array();
I read the certificate
if (!$cert_store = file_get_contents(/path/to/cert.pfx")) {
echo "Error: Unable to read the cert file\n";
exit;
}
if (openssl_pkcs12_read($cert_store, $cert_info, $pass)) {
echo "Certificate loaded\n";
}else{
echo "Error: Unable to read the cert store.\n";
exit;
}
I write the .CER certificate
$cert = $cert_info['pkey'].$cert_info['cert'].implode('', $cert_info['extracerts']);
file_put_contents(/path/to/cert.cer',$cert);
I write the .PEM certificate
$cert = $cert_info['cert'].implode('', $cert_info['extracerts']);
file_put_contents(/path/to/cert.pem', $cert);
Now, I can extract the public key from the .PEM :
$pkeydet = openssl_pkey_get_details(openssl_pkey_get_public(file_get_contents(/path/to/cert.pem')));
file_put_contents(/path/to/publick.pem', $pkeydet['key']);
Because my .CER PK is supposed to be binary, i need to use this function found on php.net to make the conversion :
function pem2der($pem_data){
$begin = "KEY-----";
$end = "-----END";
$pem_data = substr($pem_data, strpos($pem_data, $begin)+strlen($begin));
$pem_data = substr($pem_data, 0, strpos($pem_data, $end));
$der = base64_decode($pem_data);
return $der;
}
$pem_data = file_get_contents(/path/to/publick.pem');
$pem2der = pem2der($pem_data);
file_put_contents(/path/to/publick.cer', $pem2der);
NOTE: i read that a .cer file can be binary or not
I hope it is correct. I've not yet tested the generated CER but i think i'm maybe close to the solution !
Any comments/advices are welcome :)
Upvotes: 0