OK, so I’m super excited and wanted to jot down a note about RSA shared key generation.
Drama Mama
First, I wanted to generate some PEM formatted RSA public and private key pairs. I was going to do it the risky/hard way and exec openssl commands. Using exec is not a good idea if avoidable, but I was desperate. Just to put my mind at ease, I did some quick googling and found out it is possible to do this natively in PHP if you have the openssl extension installed and configured. FANTASTIC!
Then I got the curve ball. Using openssl_pkey_get_public doesn’t work as expected: it wouldn’t take a pkey resource handler and get the public key – how deceiving! I thought the thrill was over and I’d have to resort back to exec until the all mighty Brad shed his light upon us… four years ago (doh).
TL;DR
Here’s the code that generates the RSA shared key and fetched the public and private keys.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?php // generate 2048-bit RSA key $pkGenerate = openssl_pkey_new(array( 'private_key_bits' => 2048, 'private_key_type' => OPENSSL_KEYTYPE_RSA )); // get the private key openssl_pkey_export($pkGenerate,$pkGeneratePrivate); // NOTE: second argument is passed by reference // get the public key $pkGenerateDetails = openssl_pkey_get_details($pkGenerate); $pkGeneratePublic = $pkGenerateDetails['key']; // free resources openssl_pkey_free($pkGenerate); // fetch/import public key from PEM formatted string // remember $pkGeneratePrivate now is PEM formatted... // this is an alternative method from the public retrieval in previous $pkImport = openssl_pkey_get_private($pkGeneratePrivate); // import $pkImportDetails = openssl_pkey_get_details($pkImport); // same as getting the public key in previous $pkImportPublic = $pkImportDetails['key']; openssl_pkey_free($pkImport); // clean up // let's see 'em echo "\n".$pkGeneratePrivate ."\n".$pkGeneratePublic ."\n".$pkImportPublic ."\n".'Public keys are '.(strcmp($pkGeneratePublic,$pkImportPublic)?'different':'identical').'.'; ?> |
Alternatively, one could call the openssl commands directly:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php $filename = time().rand(100,999).'.tmp'; $bits = 2048; exec('/usr/bin/openssl genrsa -passout pass:1234 -des3 -out '.$filename.' '.$bits); exec('/usr/bin/openssl rsa -passin pass:1234 -in '.$filename.' -out '.$filename); $pkGeneratePrivate = file_get_contents($filename); unlink($filename); $pkImport = openssl_pkey_get_private($pkGeneratePrivate); $pkImportDetails = openssl_pkey_get_details($pkImport); $pkImportPublic = $pkImportDetails['key']; openssl_pkey_free($pkImport); echo "\n".$pkGeneratePrivate ."\n".$pkImportPublic; ?> |