John Mwaniki /   23 Jun 2023

How to Encrypt and Decrypt text using RSA in PHP

RSA is an asymmetric encryption algorithm that is widely used in various applications, including secure email communication, secure web browsing (HTTPS), and secure file transfer.

Earlier on in another article, I explained more about the RSA algorithm and how to generate RSA private and public keys on Windows and Linux.

In this article, we will explore how to encrypt and decrypt text using the RSA encryption algorithm in PHP.

In case you do not already have the encryption key(s) with you or are not aware of how to obtain them, please visit that article for more information.

  How to generate RSA private and public keys in your PC

I will use the keys below that I have already generated for encryption and decryption demonstration.

Public Key (publickey.pem)


-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAssYWg5ggPvaNRBQ/3hvO
t1cDUOsLkHtK9z+8pLPJT6e5MJTnxIe15ALmAkod0QglChTH4K0YdRfsM4thbNWS
vdcKkWShHVzwUDHa5g+pCtjOjurvn7kF9fahE/uP04X1wvO1+D+a9YRn3PsLOnJw
D0cSGGbuTOBXwIFNuUp23X1bdW2e/IHdTjphET4FHt1uvpnwJuYFP+jGK168Fukx
NOmfoLnxMc7qRKYudNxLA2T0a9TGtT62l9RD1jmkbvbjDJkGajawTClijHG+JMO7
b34QBZZFC06uaWI78idZix4GtvKhjq20BNflmi83b/f/JBQVPDFJMciMfNrsNky1
eQIDAQAB
-----END PUBLIC KEY-----

Private Key (privatekey.pem)


-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCyxhaDmCA+9o1E
FD/eG863VwNQ6wuQe0r3P7yks8lPp7kwlOfEh7XkAuYCSh3RCCUKFMfgrRh1F+wz
i2Fs1ZK91wqRZKEdXPBQMdrmD6kK2M6O6u+fuQX19qET+4/ThfXC87X4P5r1hGfc
+ws6cnAPRxIYZu5M4FfAgU25SnbdfVt1bZ78gd1OOmERPgUe3W6+mfAm5gU/6MYr
XrwW6TE06Z+gufExzupEpi503EsDZPRr1Ma1PraX1EPWOaRu9uMMmQZqNrBMKWKM
cb4kw7tvfhAFlkULTq5pYjvyJ1mLHga28qGOrbQE1+WaLzdv9/8kFBU8MUkxyIx8
2uw2TLV5AgMBAAECggEAAZ2MN7vL+f9GWLaKITRFH1KYKa05P7pgrtbfmhyZyON6
5x2uJN0V33qU0354W7Qw7+Qu+v1b1DfXUlvqRHTlmSha5LEKsUMIVOEucv4lokuo
cJHE51kuEAJR6eYcomYUFqMXInTvFIerj8ttvYup+ylcPrMBAkBthCrNWTHhqXyw
zKlMSAucvO1HlB0Nt3puzEEmLvwnoJibnCjI7NsfFB0Njv24iv4hQo3oYzppdSNi
XsNfHFAwNquJZkaLJNiMhGkg9qTyPAWU3EOMYqqYOy+7z6TTIoK56JlV0L2XfnWm
dadCT9xgSoydbd1IXfsNHMPDZzUfciEi7d/FJJ0apQKBgQD0KEleXle7SvdJnUPU
hD3X2Ae7reaOU67Ug3IK7BftzatrVbUVj9tZTs2n3iR31eV9nVFPD/MPl/FfFC05
gCwYrVGLzL7fI3SjBnyv3bJhbqCQJOoJMaIi6bT8iCZnnOHXrtGuc5moEPXHiAfJ
7mldeKESdDaN9yXs+a7supsR3wKBgQC7ce4np/rvM8HK2tj6KlZTxade3XzooqLQ
YlQlFr07x6wlk4W1Mk236oiqEF0YGxB+F4I5noJTMnw9HK4rvLF5dzU/Z0xhpJep
t2gyEIWYLKC4mnQ3/NXzG14L8HEQr+xrKUbrW/g6aZeZwclvYXk8ggDmsfb9mwrz
oXm3Nj+TpwKBgQCit9q1ztBPXVXTNMFI990zZaE5vlsCjdjdfsDZcKE99i0BOryV
oys/qNo8vzq0ttPcVKUkuO93e/78K7k8MiSxSYkoT4sBsWKBZ8hfeLPyZUUS69ch
y3dQJ0tcZeyabx7AnJzX0+ka7jqvAQSX2pFUHxnR76uQD5+yAHFJCdBhJwKBgEa8
q/9TKSN0CMIg7JkbuRBMGul19FlmZsL1GIQWnLsekxxrG55RqXqqi4CCRF+Adyze
ekp8Qvpapv/4/tGKl/8auYF/3hdLIeDuUefyzDetP8nqn8kxJRxlS4x95G1DtpiK
LzVKs9Z3WrqvovDhe/sVpHlq16bFB9EBMwms8zkpAoGBAJqixxe6VqF25ZmRiz3m
FzCrUJPcy8GqJ1hnbMOw2tiPh27K2GmvOvE7l/cKV53whR0FprnemZKa3L+wG/XM
urV+FmkojS3eLcNiwlBdaEjASe6JOhxmSI21LqWSoPJeV3rtN+K/8b9FBivshGak
7s7iqP6MRwS+u5lax61nbKue
-----END PRIVATE KEY-----

Either of the keys can be used to encrypt the data, while the other key is used to decrypt it. For instance, if the public key is used for encryption, the corresponding private key must be used to decrypt the data and vice versa.

Encrypting data with the Public key

Encryption with the public key is the most common method and the applicable one when sending sensitive/confidential information across a network such as the Internet. This is because using this method, only the recipient (who possesses the private key) can decrypt and read the data.

First, we assign the public key to a variable by copying the file's content and pasting it directly to the variable value as a string, or by using the openssl_pkey_get_public() or get_file_contents() functions to get the public key from the publickey.pem file.

$publickey = openssl_pkey_get_public("file://path/to/publickey.pem");
// Or
$publickey = get_file_contents("path/to/publickey.pem");
// Or
$publickey = "Paste the file content here";

We then use the openssl_public_encrypt() function to encrypt the data with the public key.

Syntax

openssl_public_encrypt($data, $encrypted_data, $publickey, $padding)

This function returns true on success or false on failure.

Parameters Description

Parameter Requirement Description
data Required Specifies the plaintext data to be encrypted.
encrypted_data Required Specifies a variable that will hold the result of the encryption (ie the encrypted data).
publickey Required Specifies the public key to be used in the encryption.
padding Optional Specifies a padding scheme to be used together with RSA encryption. Its value can be either OPENSSL_PKCS1_PADDING, OPENSSL_SSLV23_PADDING, OPENSSL_PKCS1_OAEP_PADDING, or OPENSSL_NO_PADDING.

Example

<?php
$publickey = openssl_pkey_get_public("file://publickey.pem");
$mytext = "The quick brown fox jumps over the lazy dog";
openssl_public_encrypt($mytext, $encrypted, $publickey);
echo $encrypted;
?>

Output:
�Nm�s�,We�W�����x8\�vu�������(���La����ڧ�����?��p���t�n��L��C3i�[&����+t�Db�i5n?ml�dL}�`ԻWya��������ީ�P+��ʛ��Q�I���q=��6���y�ۓ��vJ�cQj�N?�L��Q�l�q5*��.b�T��L���j��I����a��|]�fSv���.����ѥ��]��$��пi�S�i�Ԥ��F_� e��:?�yf7�

The above example shows that the output (ciphertext) looks scrambled and incoherent. The PHP script and the public key file are in the same directory. The default padding scheme in RSA encryption is OPENSSL_PKCS1_PADDING. So from the fact that we omitted the padding parameter in the example, the default was used.

To use a different padding scheme (or none) in the encryption, make sure to specify its respective constant as the fourth parameter.

Example

<?php
$publickey = get_file_contents("publickey.pem");
$mytext = "The quick brown fox jumps over the lazy dog";
openssl_public_encrypt($mytext, $encrypted, $publickey, OPENSSL_PKCS1_OAEP_PADDING);
echo $encrypted;
?>

Output:
9�+F92d�bj�A0c�_���Hz�#��'�*麐C%�@e��6@?�=��u/������5 ��Q �k�t�� H �1Eչ���}�B�T�;����b�k.R���R`rqAc� 'mχO�>���pzu�"�0E?��m[%<�-G�/�,�b�=��i3�>�"��1qG=8�.oѯ{yēI�4�AXQazK�c�z�V4/��**�=��*�4>$RP������ He�d�@��j��!����

It is important to note that RSA encryption padding is randomized. The same message encrypted multiple times will look different each time.

Decrypting data with Private Key

To decrypt the data encrypted with the public key, you need to use the openssl_private_decrypt() function with the corresponding private key.

Syntax

openssl_private_decrypt($encrypted_data, $decrypted_data, $privatekey, $padding)

This function returns true on success or false on failure.

Parameters Description

Parameter Requirement Description
encrypted_data Required Specifies the ciphertext to be decrypted.
decrypted_data Required Specifies a variable that will hold the result of the decryption process (ie the plaintext data).
privatekey Required Specifies the private key corresponding to the public key used in the encryption.
padding Optional Specifies a padding scheme to be used together with RSA decryption. It MUST be the same that was used during the encryption. Its value can be either OPENSSL_PKCS1_PADDING, OPENSSL_SSLV23_PADDING, OPENSSL_PKCS1_OAEP_PADDING, or OPENSSL_NO_PADDING.

Example

<?php
$publickey = openssl_pkey_get_public("file://publickey.pem");
$privatekey = openssl_pkey_get_private("file://privatekey.pem");
$mytext = "The quick brown fox jumps over the lazy dog";

echo "Before encryption: ".$mytext."<br><br>";

openssl_public_encrypt($mytext, $encrypted, $publickey);
echo "Encrypted data:<br>".$encrypted."<br><br>";

openssl_private_decrypt($encrypted, $decrypted, $privatekey);
echo $decrypted;
?>

Output:
Before encryption: The quick brown fox jumps over the lazy dog

Encrypted data:
iן�^�s PP_W�5ܬmp��� ���A�o�K�����4����ȫ���0w���1�T����}W�����=R[S7a�Ilz�p��ـ�����)Y�^?R���/hC��`��L�褧��E A�y�/5抩F�F�x�x���n��\�/iN����_�H�<�3�p|bS����㸑Q�Þ��^-0oݟ�߻�� ;�y��q���x�fӋ�}��v�����_���z0�7��Gkx�@�A ��c5認4

The quick brown fox jumps over the lazy dog

Encrypting data with the Private key

Encryption with the private key is done only to verify the identity of the sender but does not protect the data from being read in transit. This is because the encrypted data (ciphertext) is usually sent together with the public key (for decrypting) to the recipient. Thus anyone who accesses the data can use the public key to decrypt and read it.

Encryption of data with a private key is done using the openssl_private_encrypt() function.

Syntax

openssl_private_encrypt($data, $encrypted_data, $privatekey, $padding)

Parameters Description

Parameter Requirement Description
data Required Specifies the plaintext data to be encrypted.
encrypted_data Required Specifies a variable that will hold the result of the encryption.
privatekey Required Specifies the private key to be used in encrypting the data.
padding Optional Specifies a padding scheme to be used together with RSA encryption. Its value can be either OPENSSL_PKCS1_PADDING or OPENSSL_NO_PADDING.

Example

<?php
$privatekey = openssl_pkey_get_private("file://privatekey.pem");
$mytext = "The quick brown fox jumps over the lazy dog";
openssl_private_encrypt($mytext, $encrypted, $privatekey);
echo $encrypted;
?>

Output:
>����dd6#�� �bQ��@ @��>v I��m^��ᓺ��|�}��� ��hgM打��PG1R ���>�,HQ!8�}0��fA�"��x2x����!֘s�>��ȁq݅��{s���)|�s���3r��j|���>��E+��Tq�8��!�آ��bH����~k�� w�;}W���N��S�OMD,��OX7��5�OCY�

In this example, the private key file and the PHP script are located in the same directory. Same as in the public key encryption, the default padding scheme is OPENSSL_PKCS1_PADDING, which is only the available one or no padding.

Decrypting data with Public Key

To decrypt the data encrypted with the private key, you will need to use the openssl_public_decrypt() function with the corresponding public key.

Syntax

openssl_public_decrypt($encrypted_data, $decrypted_data, $publickey, $padding)

This function returns true on success or false on failure.

Parameters Description

Parameter Requirement Description
encrypted_data Required Specifies the ciphertext to be decrypted.
decrypted_data Required Specifies a variable that will hold the result of the decryption process.
publickey Required Specifies the public key corresponding to the private key used in the encryption.
padding Optional Specifies a padding scheme to be used together with RSA decryption. It MUST be the same that was used during the encryption. Its value can be either OPENSSL_PKCS1_PADDING or OPENSSL_NO_PADDING.

Example

<?php
$publickey = openssl_pkey_get_public("file://publickey.pem");
$privatekey = openssl_pkey_get_private("file://privatekey.pem");
$mytext = "The quick brown fox jumps over the lazy dog";

echo "Before encryption: ".$mytext."<br><br>";

openssl_private_encrypt($mytext, $encrypted, $privatekey);
echo "Encrypted data:<br>".$encrypted."<br><br>";

openssl_public_decrypt($encrypted, $decrypted, $publickey);
echo $decrypted;
?>

Output:
Before encryption: The quick brown fox jumps over the lazy dog

Encrypted data:
>����dd6#�� �bQ��@ @��>v I��m^��ᓺ��|�}��� ��hgM打��PG1R ���>�,HQ!8�}0��fA�"��x2x����!֘s�>��ȁq݅��{s���)|�s���3r��j|���>��E+��Tq�8��!�آ��bH����~k�� w�;}W���N��S�OMD,��OX7��5�OCY�

The quick brown fox jumps over the lazy dog

That's it!

Now you know how to encrypt and decrypt data in PHP and safeguard it from unauthorized access (or verify the sender's identity) using the RSA algorithm.