Blog de programación, errores, soluciones

Chose Language:
Author: Admin/Publisher |finished | checked

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/#introduction

What 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.

The original Caesar cipher moved the letters 3 spaces to the right. The previous cipher is just an example.

Cipher Today

https://blastcoding.com/en/data-encryption-in-php/#cipher_today

Today 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)

AlgoritmoLongitud del hashTamaño total (sin overhead)
MD516 bytes16000 bytes
SHA-25632 bytes32000 bytes
SHA-120 bytes20000 bytes
Blowfish448 bits (56 bytes)56000 bytes
Blowfish (448 bits):56 bytes56000 bytes
Blowfish (128 bits):16 bytes16000 bytes
Argon232-128 bytes (configurable)32000-128000 bytes
Argon2i (128 bits):32 bytes32000 bytes
Argon2i (256 bits):48 bytes48000 bytes
Argon2id (128 bits):40 bytes40000 bytes
Argon2id (256 bits):56 bytes56000 bytes
Bcrypt60 bytes60000 bytes
el overhead corresponde a un 10% más

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.

Algorithms like MD5, SHA1, or SHA256 are no longer recommended for use in passwords. That’s why in password encryption, you will see different algorithms than these.

Password Encryption in PHP

https://blastcoding.com/en/data-encryption-in-php/#password_encryption

In 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_hash

creates a password hash

Description / Descripción
 password_hash(string $password, string|int|null $algo, array $options = []): string
Important things to keep in mind when using this function:
  • 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

password_verify

https://blastcoding.com/en/data-encryption-in-php/#password_verify

The 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ón
password_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.

Ejemplo de php.net
// 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_data

To 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_length

Determines the length of the initialization vector for an encryption algorithm and mode.

Description / Descripción
openssl_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_bytes

Creates a pseudo-random string with the specified number of bytes.

Description / Descripción
openssl_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.

In this parameter, you don’t have to pass a value true or false, but you should pass a variable where this value will be stored.

openssl_encrypt

https://blastcoding.com/en/data-encryption-in-php/#openssl_encrypt

Encrypts the data, resulting in a string.

Description / Descripción
 
openssl_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

https://es.wikipedia.org/wiki/Modos_de_operaci%C3%B3n_de_una_unidad_de_cifrado_por_bloques
Ejemplo de encriptación con openssl_encrypt
$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_decrypt

decript the data

Description / Descripción
  
 openssl_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_data

It’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.

Category: en-php
Something wrong? If you found an error or mistake in the content you can contact me on Twitter | @luisg2249_luis.
Last 4 post in same category