Data encryption in PHP
Today we will see how we can encrypt data in PHP, but first of all, we should take a look at what encryption is.
Introduction
https://blastcoding.com/en/data-encryption-in-php/#introductionWhat is encryption? Encrypting is equivalent to ciphering
It is a method that increases the security of a message or a file by encoding the content so that only the person with the appropriate encryption key can decode it.
wikipedia
Let’s look at a simple cipher to better understand the concept, for example, the Caesar cipher, which shifts each letter by a certain number of spaces. Let’s suppose we have the alphabet and we move all the letters back or to the left by 2 spaces.
In this example, A will become Y, B will become Z, C will become A, and so on.
Cipher Today
https://blastcoding.com/en/data-encryption-in-php/#cipher_todayToday we have a variety of ciphers that can be helpful. Some ciphers are less secure while others are more secure.
Keep in mind that encrypting each piece of data also takes up a certain amount of space.
Space occupied by different encryption algorithms (1000 pieces of data with 100 characters each)
Algoritmo | Longitud del hash | Tamaño total (sin overhead) |
---|---|---|
MD5 | 16 bytes | 16000 bytes |
SHA-256 | 32 bytes | 32000 bytes |
SHA-1 | 20 bytes | 20000 bytes |
Blowfish | 448 bits (56 bytes) | 56000 bytes |
Blowfish (448 bits): | 56 bytes | 56000 bytes |
Blowfish (128 bits): | 16 bytes | 16000 bytes |
Argon2 | 32-128 bytes (configurable) | 32000-128000 bytes |
Argon2i (128 bits): | 32 bytes | 32000 bytes |
Argon2i (256 bits): | 48 bytes | 48000 bytes |
Argon2id (128 bits): | 40 bytes | 40000 bytes |
Argon2id (256 bits): | 56 bytes | 56000 bytes |
Bcrypt | 60 bytes | 60000 bytes |
It’s not much, but it’s something. For every 100,000 entries, if one column uses bcrypt, it will use 6 MB.
In general, encryption can increase the size of the database by 10% to 400% or more. This can be a significant issue for large databases with limited space.
The ideal approach is to use strong encryption for passwords like bcrypt, and weaker encryption for, for example, email addresses and other data. Some data can often be stored without encryption when dealing with sensitive data, although this is not recommended.
Password Encryption in PHP
https://blastcoding.com/en/data-encryption-in-php/#password_encryptionIn PHP, we have 2 functions that handle both password encryption and verification of the password entered by the user. These are password_hash
and password_verify
, and they are recommended for use in PHP. Specifically, password_hash
allows us to use bcrypt, which is highly secure.
¿What is a hash?
A cryptographic hash function—commonly known as a “hash”—is a mathematical algorithm that transforms any arbitrary block of data into a new series of characters with a fixed length. Regardless of the length of the input data, the resulting hash value will always have the same length.
https://latam.kaspersky.com/blog/que-es-un-hash-y-como-funciona/2806/
Now that we have a clearer understanding of what a hash is, let’s quickly look at these 2 functions: password_hash
and password_verify
.
password_hash
https://blastcoding.com/en/data-encryption-in-php/#password_hashcreates a password hash
Description / Descripciónpassword_hash(string $password, string|int|null $algo, array $options = []): string
- 1- The column storing passwords should have a length of more than 60 characters, with 255 being recommended.
- 2- The password passed to the function is truncated to 72 characters.
- 3- The constant
PASSWORD_DEFAULT
is designed to use the strongest algorithm available, so it may change in the future. - 4- The salt option has been deprecated starting from PHP 7.
$password
– the password of the user who is registering.
$algo
– is the algorithm we will use. One of the supported algorithms.
The supported algorithms for password_hash
are the following ones:
PASSWORD_DEFAULT
PASSWORD_BCRYPT
PASSWORD_ARGON2I
PASSWORD_ARGON2ID
$options
– options that the algorithm has.
Let’s see an example of password_hash
.
<?php // Configuración de la base de datos $host = 'localhost'; $dbname = 'nombre_base_de_datos'; $username = 'usuario'; $password = 'contraseña'; try { // Conexión a la base de datos utilizando PDO $pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Datos del usuario (nombre, email y contraseña) $nombre = 'Juan'; $email = 'juan@example.com'; $contrasena = 'contraseña_segura'; // Hash de la contraseña utilizando password_hash $hashedPassword = password_hash($contrasena, PASSWORD_DEFAULT); // Preparar la consulta SQL para insertar datos en la tabla de usuarios $statement = $pdo->prepare("INSERT INTO usuarios (nombre, email, contrasena) VALUES (:nombre, :email, :contrasena)"); // Vincular parámetros $statement->bindParam(':nombre', $nombre); $statement->bindParam(':email', $email); $statement->bindParam(':contrasena', $hashedPassword); // Ejecutar la consulta $statement->execute(); echo "Usuario registrado correctamente."; } catch(PDOException $e) { // En caso de error, mostrar el mensaje de error echo "Error: " . $e->getMessage(); }
I know I should create a form and validate the inputs and other things, but for practical purposes, this example should suffice to understand how to use it.
If you’re more experienced in the field, you might wonder what happens with the salt that is used.
Starting from one of the new versions of PHP, the salt is included within the same column as the password, which is recommended on the official PHP website. In fact, in PHP 8, the salt you provide to the function will not be considered.
The password column will have the following:
If you want to delve deeper into the topic, I recommend reading this: https://www.php.net/manual/en/faq.passwords.php
[ADS_FD/]password_verify
https://blastcoding.com/en/data-encryption-in-php/#password_verifyThe password_verify
function verifies that a password matches a hash.
Its general use is to verify if a password entered by a user or during login matches the hash associated with that user.
Description / Descripciónpassword_verify(string $password, string $hash): bool
$password
– password entered in an input field, typically by the user attempting to log in.
$hash
– a hash created by password_hash
, usually retrieved from the database.
// See the password_hash() example to see where this came from. $hash = '$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a'; if (password_verify('rasmuslerdorf', $hash)) { echo 'Password is valid!'; } else { echo 'Invalid password.'; }
Now, you may wonder, “How do I obtain the hash?”
The hash is obtained from the database. In reality, you should retrieve the data by the username, which should always be unique, or it could also be by their email, which should also be unique.
Encrypt sensitive data in PHP
https://blastcoding.com/en/data-encryption-in-php/#sensitive_dataTo secure sensitive data, you will need to use AES (Advanced Encryption Standard) algorithms. For this, you can use the openssl_encrypt
and openssl_decrypt
functions.
Do not use hashes for this purpose.
Let’s go through all the functions you would need to use for encryption using the OpenSSL extension. But first, remember that you will be using OpenSSL, so you need to have it installed.
Make sure to enable OpenSSL in your Apache by uncommenting the line ;extension=openssl.so
in your php.ini.
Next, we will see the functions we will use for encryption:
openssl_cipher_iv_length
https://blastcoding.com/en/data-encryption-in-php/#openssl_cipher_iv_lengthDetermines the length of the initialization vector for an encryption algorithm and mode.
Description / Descripciónopenssl_cipher_iv_length(string $cipher_algo): int|false
$cipher_algo
– algorithm we will use.
Returns
int
– cipher length
false
– in case of error
openssl_random_pseudo_bytes
https://blastcoding.com/en/data-encryption-in-php/#openssl_random_pseudo_bytesCreates a pseudo-random string with the specified number of bytes.
Description / Descripciónopenssl_random_pseudo_bytes(int $length, bool &$strong_result = null): string
$length
– the desired length of the string
$strong_result
(by reference)
This parameter is not one we will use, and therefore, we will use its default value null. This value itself determines whether the algorithm is considered cryptographically strong.
openssl_encrypt
https://blastcoding.com/en/data-encryption-in-php/#openssl_encryptEncrypts the data, resulting in a string.
Description / Descripciónopenssl_encrypt( string $data, string $cipher_algo, string $passphrase, int $options = 0, string $iv = "", string &$tag = null, string $aad = "", int $tag_length = 16 ): string|false
This function has a large number of parameters, so we will look at those that are of interest for the demonstration of simple encryption that we want to perform.
$data
– the data to be encrypted
$cipher_algo
– the cipher algorithm we are using
$passphrase
– encryption key
$iv
– Initialization Vector (IV)
This parameter is not always necessary when using openssl_encrypt
, but it will be necessary in this case, as we will be using CBC.
imagen de CBC sacada de Wikipedia
$e_key = "EncryptionKey";//la llave de encripcion que deseas ponerle $data = "Sensitive data";//datos a ser encriptados $method = "aes-256-cbc";//algoritmo y opciones $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($method)); // Encrypt the data $encrypted_data = openssl_encrypt($data, $method, $e_key, 0, $iv); echo $encrypted_data;//si hago un echo
Uos8EIOxD6DuuQXyhxTKoQ==
openssl_decrypt
https://blastcoding.com/en/data-encryption-in-php/#openssl_decryptdecript the data
Description / Descripciónopenssl_decrypt( string $data, string $cipher_algo, string $passphrase, int $options = 0, string $iv = "", ?string $tag = null, string $aad = "" ): string|false
$data
– in this case, $data
will receive the encrypted data
We will also use: $cipher_algo
, $passphrase
, and $iv
Let’s see how they would be used. I have made this decryption example continue from what we saw in encryption, so $d_data
will have the value "Sensitive data" (string)
.
$d_data = openssl_decrypt($encrypted_data, $method, $e_key, 0, $iv); echo "\n Decrypted data: $d_data";
Decrypted data: Sensitive data
Other ways to encrypt sensitive data
https://blastcoding.com/en/data-encryption-in-php/#other_ways_to_encrypt_sensitive_dataIt’s clear that there are third-party packages that offer us facilities for data encryption, such as libsodium, Defuse Security’s Secure PHP Encryption Library, Halite, phpseclib, sodium, etc.
Mcrypt is not on the list because it is deprecated by the PHP creators themselves; it is no longer maintained.