Cifrado y descifrado seguro de datos en PHP

2022-02-13 - Categorías: General / PHP
Keys, llaves, claves, passwords

Sencillo codekata de copia y pega en PHP para cifrar, transmitir esta información cifrada por un canal público, y descifrar en destino.

La idea es usar un cifrado con semilla, de forma que esta semilla hace que sea imposible, o muy difícil, descifrar estos datos si no se sabe dicha semilla. Generalmente, por un canal seguro y privado se comparte una clave, con esta clave se cifra en origen, y en destino igualmente se descifra.

Antes se usaban las funciones de mcrypt_ pero están deprecated en favor de las openssl_ a partir de las versiones 7 en adelante de PHP. Además, este cifrado bidireccional, es diferente a los cifrados de una dirección. Por ejemplo md5 está pensado para almacenar y nunca descifrar lo almacenado.

Resumen, funciones fáciles disponibles para cifrados con semilla

Al grano, PHP tiene disponible desde la versión 5 unas funciones que nos hacen la vida mucho más fácil:

  • openssl_encrypt
  • openssl_decrypt

Son la sucesión de las deprecated:

  • mcrypt_encrypt
  • mcrypt_decrypt

Esta función openssl_encrypt proporciona métodos de cifrado que podemos obtener así:

$cipherMethods = openssl_get_cipher_methods();
var_dump($cipherMethods);

En los que tenemos cifrados DES, AES, CAMELLIA, ARIA..

Simplemente, proporcionan una forma de cifrado de datos con semillas, con contraseñas, que son reversibles, no son de una sola dirección.

Cómo usar los openssl_encrypt y openssl_decrypt de PHP

<?php

$data = 'Esto es un texto que queremos enviar de forma segura';
$passphrase = 'ThePassword';

$cipherMethods = openssl_get_cipher_methods();
$cipherMethod = $cipherMethods[rand(0, count($cipherMethods) - 1)];
echo 'Using cypher method: '.$cipherMethod.PHP_EOL;

try {
    $inicializationVectorLength = openssl_cipher_iv_length($cipherMethod);
} catch (Exception $e) {
    echo 'ERROR getting IV length, using 256'.PHP_EOL;
    $inicializationVectorLength = 256;
}
$inicializationVector = openssl_random_pseudo_bytes($inicializationVectorLength);
echo 'Inicialization vector: '.$inicializationVector.PHP_EOL;

echo 'Data to encrypt: '.$data.PHP_EOL;
$encryptedData = openssl_encrypt($data, $cipherMethod, $passphrase, OPENSSL_RAW_DATA, $inicializationVector);
echo 'Encrypted data:  '.$encryptedData.PHP_EOL;
$decryptedData = openssl_decrypt($encryptedData, $cipherMethod, $passphrase, OPENSSL_RAW_DATA, $inicializationVector);
echo 'Descrypted data: '.$decryptedData.PHP_EOL;

Por ejemplo, esto puede funcionar así:

Otro caso de uso, hacer un hash descifrable para usar en una URL

Otro supuesto, supongamos que queremos enviar links, que apunten a cierta información. Para esto podemos elegir que el tercer parámetro sea codificado en base64, entonces bastaría con poner un false, cero o OPENSSL_ZERO_PADDING:

echo 'Data to encrypt: '.$data.PHP_EOL;
$encryptedData = openssl_encrypt($data, $cipherMethod, $passphrase, OPENSSL_ZERO_PADDING, $inicializationVector);
echo 'Encrypted data:  '.$encryptedData.PHP_EOL;
$decryptedData = openssl_decrypt($encryptedData, $cipherMethod, $passphrase, OPENSSL_ZERO_PADDING, $inicializationVector);
echo 'Descrypted data: '.$decryptedData.PHP_EOL;

Entonces el resultado podría ser algo como lo siguiente:

..que sí que podemos transmitir en una URL sin problemas.

Me remito a la documentación oficial para el que quiera seguir:
https://www.php.net/manual/es/function.openssl-encrypt.php

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

 

© 2024 JnjSite.com - MIT license

Sitio hecho con WordPress, diseño y programación del tema por Jnj.