6

I'm trying to convert some .p12 files in to .pem.

On my mac it works, with no interaction as i put the passwords in the code, but when i use this code:

system('openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns-dev-cert.p12 -passin pass:');
system('openssl pkcs12 -nocerts -out apns-dev-key.pem -in apns-dev-key.p12 -passout pass:1234 -passin pass:');
system('openssl rsa -in apns-dev-key.pem -out apns-dev-key-noenc.pem -passin pass:1234');
system('cat apns-dev-cert.pem apns-dev-key-noenc.pem > apns-dev.pem');

it makes blank files.

My file permissions are 755. and for the passin the passwords were set to nothing so thats why they are blank... all the code here without the system() works in the mac terminal..

thanks for reading. hope you can help

jww
  • 97,681
  • 90
  • 411
  • 885
user633268
  • 223
  • 2
  • 3
  • 13
  • Is there a particular reason you're avoiding the built-in [`openssl_pkcs12_read`](http://us2.php.net/manual/en/function.openssl-pkcs12-read.php) function? – Charles Mar 24 '11 at 18:26
  • @Charles if it worked i would use it, but i dont know how to implement that with what i want. – user633268 Mar 24 '11 at 19:10
  • 1
    @user, The data it returns is an array including the private key, which seems to be what you're trying to extract here. You should be able to use [`openssl_pkey_export_to_file`](http://us3.php.net/manual/en/function.openssl-pkey-export-to-file.php) or [`openssl_pkey_export`](http://us3.php.net/manual/en/function.openssl-pkey-export.php) to grab the key in PEM format. – Charles Mar 24 '11 at 19:31
  • @Charles i cant get it to work right `openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns-dev-cert.p12 -passin pass:` how would i do that in PHP from the start, because from what i can see it requires .pem file in the first place or its just not getting the key. – user633268 Mar 24 '11 at 23:35

1 Answers1

23
$filename = 'apns-dev-cert.p12';
$password = '...';
$results = array();
$worked = openssl_pkcs12_read(file_get_contents($filename), $results, $password));
if($worked) {
    echo '<pre>', print_r($results, true), '</pre>';
} else {
    echo openssl_error_string();
}

Please try running this snippet. Set $password to whatever passphrase is needed to open the file. If there's no password, set it to null. I don't believe one is needed from your openssl commands.

You should get output with the desired private key, probably inside $results['pkey'].

If you see your private key there, then you can pass it to openssl_pkey_export to get it in PEM format, which you can then write to a file:

$new_password = null;
$result = null;
$worked = openssl_pkey_export($results['pkey'], $result, $new_password);
if($worked) {
    echo "<pre>It worked!  Your new pkey is:\n", $result, '</pre>';
} else {
    echo openssl_error_string();
}

Set $new_password to your desired pkey password, if you want one.

This should work for you, based on what I'm reading on the various documentation pages.


If you really want to continue using the openssl command by shelling out, please consider using proc_open instead of system, so that you can properly catch error messages.

It's also possible that OpenSSL is trying to read the config file, and doesn't have permission to so, though it should give you an error about that.

Charles
  • 50,943
  • 13
  • 104
  • 142
  • 1
    Thanks, how would you make a file for the cert bit? thanks for all your help you have been amazing. – user633268 Mar 25 '11 at 14:28
  • The certificate will *probably* be in `$result['cert']` after reading it from the PKCS12 file. You should be able to use [`openssl_x509_export`](http://www.php.net/manual/en/function.openssl-x509-export.php) to do the job. (Watch out! If you copied and pasted my code, I reused a few variable names that could make trouble. You'll need to adjust that accordingly.) – Charles Mar 25 '11 at 15:26