Asymmetric encryption using PHP
In asymmetric public/private key encription usually:
- Bob generated his public/private key pair
- Bob shared his public key
- Alice crypts some message with the public key of Bob
- She sends the message
- Only Bob can decrypt with his private key.
Now we can use the openssl library to learn basic cryptography. Note that the following code is not suitable for production software, use it only to learn the basics of asymmetric encryption.
Using that aproach and the following code Alice can succesfully send a message to Bob
/** BOB CODE **/
$key = openssl_pkey_new(array('private_key_bits' => 2048));
$bob_key = openssl_pkey_get_details($key);
$bob_public_key = $bob_key['key'];
That's the basic infrastructure you had in your code and now is code that Bob executes. Bob generates the key pair and sends to Alice, in a real environment there must be a public key sharing mechanism.
When Alice gets Bob's public key, she cyphers her message with this key:
/** ALICE CODE **/
$alice_msg = "Hi Bob, im sending you a private message";
openssl_public_encrypt($alice_msg, $pvt_msg, $bob_public_key);
Finally Bob receives the message and decrypts it
/** BOB CODE **/
openssl_private_decrypt( $pvt_msg, $bob_received_msg, $key);
print $bob_received_msg;
Recommended encryption library for production
Use libsodium if you aim for a secure production system. With it you can crypt messages...
// Generating your encryption key
$key = \Sodium\randombytes_buf(\Sodium\CRYPTO_SECRETBOX_KEYBYTES);
// Using your key to encrypt information
$nonce = \Sodium\randombytes_buf(\Sodium\CRYPTO_SECRETBOX_NONCEBYTES);
$ciphertext = \Sodium\crypto_secretbox('test', $nonce, $key);
... and decrypt messages...
$plaintext = \Sodium\crypto_secretbox_open($ciphertext, $nonce, $key);
if ($plaintext === false) {
throw new Exception("Bad ciphertext");
}
...among other things.
What is a nonce?
Check the Full manual for using it with PHP
Read it carefully, encryption is not a thing one can learn in a week. There are some caveats.
The whole idea of public-key cryptography is that every 'user' has a 'Public key' and a 'Private key'. There are 3 main implementations for these keys: confidential, authenticated and combined. In my answer, I'll go by the 'confidential' technique.
Each user has a 'Public key' that they distribute and which will be used by the other user to encrypt the message that will be sent back, and a 'Private key' that they keep only for themselves which is used to decrypt the messages that they will receive. The key that you have used to encrypt your message, isn't the same key that is used to decrypt.
Example of 'confedential key use':
Bob has: Bob private key, Bob public key, Alice public key
Alice has: Alice private key, Alice public key, Bob public key
Bob wants to send a message to Alice:
Bob uses 'Alice public key' to encrypt the message, sends it =>
Alice uses 'Alice private key' to decrypt the message.
Alice wants to reply and sends a message to Bob:
Alice uses 'Bob public key' to encrypt the message, sends it =>
Bob uses 'Bob private key' to decrypt the message.
Public key is only used to encrypt message
Private key is only used to decrypt message encrypted with Public key
Now that you know what the basic idea of the 'Public key' and 'Private key' is, have a look at this image explaining the typical SSL communication and the use of the keys.
Signatures, a kind of hash proving the owner of the private key created the encrypted message. Good for Alice to prove Bob wrote her a message (encrypted with Alice's public key) - rather than Joe. Bob creates a unique signature using his private key, which Alice can confirm using Bob's public.
:)