How to encrypt data in php using Public/Private keys? How to encrypt data in php using Public/Private keys? php php

How to encrypt data in php using Public/Private keys?


Creating a private and public key pair using the PHP Openssl functions:

// Configuration settings for the key$config = array(    "digest_alg" => "sha512",    "private_key_bits" => 4096,    "private_key_type" => OPENSSL_KEYTYPE_RSA,);// Create the private and public key$res = openssl_pkey_new($config);// Extract the private key into $private_keyopenssl_pkey_export($res, $private_key);// Extract the public key into $public_key$public_key = openssl_pkey_get_details($res);$public_key = $public_key["key"];

You can then encrypt and decrypt using the private and public keys like this:

// Something to encrypt$text = 'This is the text to encrypt';echo "This is the original text: $text\n\n";// Encrypt using the public keyopenssl_public_encrypt($text, $encrypted, $public_key);$encrypted_hex = bin2hex($encrypted);echo "This is the encrypted text: $encrypted_hex\n\n";// Decrypt the data using the private keyopenssl_private_decrypt($encrypted, $decrypted, $private_key);echo "This is the decrypted text: $decrypted\n\n";


I would create S/MIME public/private keypairs using OpenSSL and then use the OpenSSL command to do the encryption & decryption. I believe that this is superior to using PGP because openssl is included with most linux operating systems and PGP isn't. OpenSSL is also standards-based and generally easier to work with, once you have the commands down.

I recommended against a "pure-PHP" solution (by pure-PHP I mean doing the crypto in PHP, rather than using PHP to call an existing library or a separate executable). You don't want to do bulk crypto in PHP. Too slow. And you want to use OpenSSL, because it's high performance and the security is well understood.

Here's the magic.

To make an X.509 key:

$subj="/C=US/ST=California/L=Remote/O=Country Govt./OU=My Dept/CN=Mr. Agent/emailAddress=agent@investiations.com"openssl req -x509 -newkey rsa:1024 -keyout mycert.key -out mycert.pem -nodes -subj $subj

That puts the private key in mycert.key and the public key in mycert.pem. The private key is not password protected.

Now, to sign a message with S/MIME:

openssl smime -sign -signer mycert.pem -inkey mycert.key <input >output

To encrypt a message with S/MIME:

openssl smime -encrypt -recip yourcert.pem <input >output

To decrypt a message with S/MIME:

openssl smime -decrypt -inkey mycert.key -certfile mycert.pem <input >output

I also have some demos on using OpenSSL from the C language bindings, but not from PHP.


Rule 1: Don't implement it yourself, use a library.

Which library? Here are my recommended PHP public-key cryptography libraries:

  1. Halite, depends on libsodium (but emphasizes simplicity and ease-of-use in addition to security).
  2. libsodium, from PECL
  3. EasyRSA, which implements secure public-key encryption and public-key signatures using RSA in the most secure modes (NOT PKCS1v1.5, ever!)
  4. phpseclib, which EasyRSA piggybacks off of.

In general, you'll want libsodium if security is your goal. Whether or not you use Halite is a matter of taste.