Lecture
Symmetric encryption is an encryption algorithm in which the same cryptographic key is used both to encrypt and to decrypt data. Let's look at PHP data encryption using the symmetric method based on the AES (Advanced Encryption Standard) algorithm – a symmetric block cipher algorithm (block size 128 bits, key 128/192/256 bits). AES is one of the most widely used symmetric encryption algorithms..
As already mentioned, encryption and decryption require an encryption key. This can be any string, but to obtain it we'll use a function that generates a pseudo-random byte string 40 bytes long, and convert the result into hexadecimal representation:
$bytes = openssl_random_pseudo_bytes(40);
$hex = bin2hex($bytes);
var_dump($hex);
The screen will display a result of the following form:
string(80) "5aa3c281e42ba7101f7227a7519d5e961c734340a42914304bffc1afcebb1d2be98f53caa80d05"
We will use the resulting value as the secret key for encrypting and decrypting data (it must be kept secret). Let's store it in the variable $key:
$key = "5aa3c281e42ba7101f7227a7519d5e343434344304bffc1afcebb1d2be98f53caa80d05";
Now let's decide what we'll be encoding. For the first example we'll take a plain string:
$data = 'Это строка закодирована симметричным алгоритмом шифрованием AES';
We will encrypt the data using the AES algorithm with a 192-bit key:
$method = "AES-192-CBC";
All available encryption methods can be viewed as follows:
var_dump(openssl_get_cipher_methods());
Having the data to encrypt $data, the chosen method $method, and the secret key $key, in PHP we can perform symmetric data encryption using the openssl_encrypt function:
$encrypted = openssl_encrypt($data, $method, $key);
Let's display the result using var_dump($encrypted):
string(152) "qNiTUkY5GY63q2IjbZ034myIFAf7hyTX+dRJF4YjJmJCk15Yq34343gpECKlCmLEgft7WNUV3/yZVcSqxLO3aDDOoV/5oglU1hFRiLD9yBF9q6HrM0Ic2e0RCgXxaHFa6ae6dZ2mVzgSkZvZnasTYg=="
To decrypt the resulting value, we need to use the inverse function openssl_decrypt:
$decrypted = openssl_decrypt($encrypted, $method, $key);
Let's use var_dump($decrypted) again:
string(107) "Это строка была закодирована симметричным шифрованием AES"
The complete listing of the symmetric encryption/decryption example in PHP is as follows:
?php>
In PHP, file encryption differs from data encryption only in that the file's contents must first be read, then have the necessary operations performed on them, and then be written back.
Let's create a plain text file in the current directory:
$ echo 'Этот файл кодирован на PHP с помощью симметричного алгоритма AES' > aes.txt
We'll take the key and encryption method from the previous example, and get the data to encode from the aes.txt file using the file_get_contents function:
$key = "5aa3c281e42ba7101f7227a7519d5e961c7bcf34344304bffc1afcebb1d2be98f53caa80d05";
$method = "AES-192-CBC";
$file = 'aes.txt';
$contents = file_get_contents($file);
Let's encode the file's contents and write them to a new file aes-encrypted.txt using the file_put_contents function:
$contetsEncrypted = openssl_encrypt($contents, $method, $key);
$fileEncrypted = 'aes-encrypted.txt';
file_put_contents($fileEncrypted, $contetsEncrypted);
Let's look at the contents of the resulting file:
$ cat aes-encrypted.txt
u1IdVyyNwECahzAaN0DQdSPx4lDiXHKXWc8/yl6KLne3tcyT/vUD/96ZerferferYT7JxiShat9xUjdQEC5V2nLuuMZ1/yUmIsE4HKZcvZEki99e0gAdtP9M0vdo82rEUfFnKe78wT7/zeOs1PBLaQvpXWbM8VcVeEVzTc=
All that's left is to try decrypting this file and writing it out:
$contents = file_get_contents($fileEncrypted);
$contentsDecrypted = openssl_decrypt($contents, $method, $key);
$fileDecrypted = 'aes-decrypted.txt';
file_put_contents($fileDecrypted, $contentsDecrypted);
Let's check the result:
$ cat aes-decrypted.txt
Этот файл кодирован на PHP с помощью симметричного алгоритма AES
The complete listing of symmetric AES file encryption in PHP:
?php>?php>
Asymmetric encryption differs from symmetric encryption in that encrypting and decrypting data uses not one shared key, but two different ones. One of the most widely used asymmetric encryption algorithms is RSA (an abbreviation of the names Rivest, Shamir, and Adleman) — a public-key cryptographic algorithm. In this algorithm, a public key is used to encrypt data, and a secret private key is used to decrypt it.
To work with this algorithm we'll need a public key public.crt and a private key private.pem. They can be obtained from the console using openssl. Let's generate an rsa pair with a 2048-bit key valid for 365 days (“/C=RU/ST=MO/L=MOSCOW/O=POCKETADMIN/TECH=XX/CN=intellect.icu/emailAddress=”example@intellect.icu – information about the subject that issued the key):
$ openssl req -newkey rsa:2048 -nodes -keyout private.pem -out public.crt -x509 -days 365 -subj "/C=RU/ST=MO/L=MOSCOW/O=POCKETADMIN/TECH=XX/CN=intellect.icu/emailAddress="example@intellect.icuGenerating a 2048 bit RSA private key ..................................................................+++ .+++ writing new private key to 'private.pem' ----- Subject Attribute TECH has no known NID, skipped
Let's declare the string to encrypt and the keys:
$data = 'Эта строка была зашифрована на PHP асимметричным алгоритмом RSA';
$filePublicKey = 'public.crt';
$filePrivateKey = 'private.pem';
Once again, I want to point out that the private key itself must be kept secret! To perform encryption, it's enough to give third parties only the public key.
Let's get the contents of the public key file and extract the key itself:
$contentsPublicKey = file_get_contents($filePublicKey);
$publicKey = openssl_get_publickey($contentsPublicKey);
Using the openssl_public_encrypt function, we encrypt the data $data with the public key $publicKey. The encryption result will be placed into the variable $encrypted:
openssl_public_encrypt($data, $encrypted, $publicKey);
Later on, to decrypt, we'll need the private key:
$contentsPrivateKey = file_get_contents($filePrivateKey);
$privateKey = openssl_get_privatekey($contentsPrivateKey);
To decrypt the data $encrypted with the private key $privateKey, we'll use the openssl_private_decrypt function. The result is placed into the variable $decrypted:
openssl_private_decrypt($encrypted, $decrypted, $privateKey);
Let's check the result using var_dump($decrypted):
string(112) "Эта строка была зашифрована на PHP асимметричным алгоритмом RSA"
Here is the complete PHP code for RSA data encryption:
?php>?php>?php>
Let's create a simple text file that we'll encrypt:
$ echo 'Этот файл был зашифрован на PHP асимметричным алгоритмом RSA' > rsa.txt
We'll use the public and private key from the previous example. Let's declare the file to encrypt, the encrypted file, and the decrypted file:
$filePublicKey = 'public.crt';
$filePrivateKey = 'private.pem';
$file = 'rsa.txt';
$fileEncrypted = 'rsa-encrypted.txt';
$fileDecrypted = 'rsa-decrypted.txt';
Similar to the previous examples: we get the public key $publicKey and use it to encrypt the contents of the file $file. We write the result to $fileEncrypted:
$contentsPublicKey = file_get_contents($filePublicKey);
$publicKey = openssl_get_publickey($contentsPublicKey);
$contents = file_get_contents($file);
openssl_public_encrypt($contents, $contentsEncrypted, $publicKey);
file_put_contents($fileEncrypted, $contentsEncrypted);
To decrypt this file: we get the private key $privateKey, decrypt the contents of the file $fileEncrypted. We write the data to the file $fileDecrypted:
$contentsPrivateKey = file_get_contents($filePrivateKey);
$privateKey = openssl_get_privatekey($contentsPrivateKey);
$contentsEncrypted = file_get_contents($fileEncrypted);
openssl_private_decrypt($contentsEncrypted, $contentsDecrypted, $privateKey);
file_put_contents($fileDecrypted, $contentsDecrypted);
Let's check the resulting file:
$ cat rsa-decrypted.txt
Этот файл был зашифрован на PHP асимметричным алгоритмом RSA
Let's put together the complete code:
<?php // Declare the files with the public and private keys
$filePublicKey = 'public.crt';
$filePrivateKey = 'private.pem';
// Declare the files: to encrypt, encrypted, and decrypted
$file = 'rsa.txt';
$fileEncrypted = 'rsa-encrypted.txt';
$fileDecrypted = 'rsa-decrypted.txt';
// Get the public key from the file
$contentsPublicKey = file_get_contents($filePublicKey);
$publicKey = openssl_get_publickey($contentsPublicKey);
// Get the file's contents, encrypt them, and write to a new file
$contents = file_get_contents($file);
openssl_public_encrypt($contents, $contentsEncrypted, $publicKey);
file_put_contents($fileEncrypted, $contentsEncrypted);
// Get the private key from the file
$contentsPrivateKey = file_get_contents($filePrivateKey);
$privateKey = openssl_get_privatekey($contentsPrivateKey);
// Decrypt the contents of the encrypted file using the private key. Write the decrypted file
$contentsEncrypted = file_get_contents($fileEncrypted);
openssl_private_decrypt($contentsEncrypted, $contentsDecrypted, $privateKey);
file_put_contents($fileDecrypted, $contentsDecrypted);
?>
Comments