Encriptar u ocultar mensajes, es algo muy común en aplicaciones de todo tipo. Cuando aprendemos un lenguaje de programación nuevo, es una de esas cosas fundamentales que debemos saber. PHP no es la excepción y dado que es un lenguaje de programación muy utilizado para construir aplicaciones web, entonces es necesario conocer como lo hace.
Antes de continuar, es importante resaltar la necesidad de encriptar no solo contraseñas, sino cualquier dato que consideremos necesario e importante, ya que guardarlo a texto plano, puede comprometer seriamente la seguridad de nuestras aplicaciones, datos y usuarios.
Tabla de Contenido
Funciones inseguras para encriptar contraseñas
Se consideran inseguras aquellas funciones que emplean algoritmo de cifrado algo antiguos o que ya han sido “rotos”, es decir, crackeados por alguien, haciéndolos obviamente inseguros. En PHP, esas funciones son MD5 y SHA1 que utilizan los algoritmos homónimos.
En el caso de MD5, dependiendo de la complejidad de la contraseña, se dice que es posible descifrarla en menos de una hora con un rango promedio de 3650 millones de cálculos por segundo. Eso significa que MD5, es el más inseguro de los algoritmos soportados.
Utilizando SHA1, es posible hacerlo en casi el mismo tiempo (de nuevo, dependiendo de la complejidad de la contraseña) pero con un rango promedio de 1360 millones de cálculos por segundo, así que tampoco es exactamente la mejor opción.
Encriptar contraseñas con MD5
Pese a que no es recomendable, por supuesto que es posible utilizar dicha función, quizá para aplicaciones que no estarán en red o por pura diversión. En todo caso, su sintaxis es la siguiente:
md5(string $string, bool $binary = false): string
Siendo que:
- $string: Es la cadena de texto a cifrar
- $binary: Si es true el hash resultado es un binario de 16 caracteres, caso contrario es de 32 caracteres.
Observe el siguiente ejemplo:
$laClave = "SoyUnaClav3#";
$res = md5($laClave, false);
echo "Clave de 32bits: $res <br />";
$res = md5($laClave, true);
echo "Clave binaria de 16bits: $res <br />";
El cual produce el siguiente resultado:

Encriptar contraseñas con SHA1
El algoritmo SHA1 establecido en el RFC3174, es un estándar que fue adoptado por el gobierno de Estados Unidos para el manejo de su información federal, sin embargo en el año 2017 ellos mismo desaconsejaron el uso de este algoritmo, ya que irónicamente la existencia de dispositivos con mayor poder de cómputo lo hace fácil de atacar y romper. La sintaxis en PHP es la siguiente:
sha1(string $str, bool $raw_output = false): string
Siendo que:
- $str – Es la cadena a cifrar
- $raw_output – Si vale true se devuelve una cadena binaria de 20 caracteres, de lo contrario se regresa un hexadecimal de 40 caracteres.
Observe el ejemplo:
$res = sha1($laClave, false);
echo "Clave hexadecimal de 40bits: $res <br />";
$res = sha1($laClave, true);
echo "Clave binaria de 20bits: $res <br />";
El cual produce el siguiente resultado.

Funciones de hash para encriptar contraseñas
Un hash es un algoritmo matemático que transforma datos en una nueva serie de caracteres con una determinada longitud. SHA1 y MD5 son funciones de hash bastante débiles, por lo que para generar un hash más confiable y potente, podemos utilizar algunas de las funciones de hash que PHP trae incluidas.
Aunque son varias las funciones que se pueden utilizar. En este artículo solo cubriremos las siguientes funciones:
- hash: Genera un valor hash
- hash_algos: Entrega una lista con los algoritmos soportados
- hash_equals: Realiza una comparación de hash segura
- hash_file: Genera un hash usando el contenido de un archivo
Cómo generar un valor hash
La función hash ofrece más opciones para encriptar contraseñas mucho más estables y seguras que MD5 y SHA1. La principal ventaja que nos da está función, es la posibilidad de elegir el algoritmo matemático con que podemos generar el hash. Su sintaxis es la siguiente:
hash(string $algo, string $data, bool $raw_output = false): string
Siendo que:
- $algo – Es el algoritmo a utilizar
- $data – Es el valor a cifrar
- $raw_output – Si es true, el resultado será un binario, en caso contrario será un hexadecimal.
Por ejemplo, aquí tenemos algunos algoritmos diferentes a MD5 y SHA1
$res = hash("sha256", $laClave, false);
echo "Clave con SHA256: $res <br />";
$res = hash("snefru", $laClave, false);
echo "Clave con Snefru: $res <br />";
$res = hash("ripemd320", $laClave, false);
echo "Clave con Ripemd320: $res <br />";
Siendo estas sus correspondientes salidas:

Mostrar la lista de algoritmos soportados
Para mostrar la lista completa de algoritmos soportados por las funciones de hash, se utiliza la función hash_algos, la cual no tiene argumentos y regresa como resultado un array con la lista completa. Por ejemplo:
print_r(hash_algos());
Y da como resultado:

Comparación segura de hashes
La función hash_equals regresa un valor booleano que puede ser falso o verdadero al comparar el string original con otro hash y ver si son iguales (true) o no (false). Su sintaxis es la siguiente:
hash_equals(string $known_string, string $user_string): bool
Donde:
- $known_string – Es el string original
- $user_string – Es el hash para comparar
Por ejemplo:
$original = hash("sha256", $laClave, false);
$comparar = hash("sha256", "SoyOtro#ash3", false);
if(hash_equals($original, $comparar)) echo "Ambos hash coinciden <br />";
else echo "Los hash no coinciden <br />";
Por supuesto que dará false, ya que ambas hash no coinciden.
Generando un hash a partir de un archivo
Por diferentes razones, es posible que se necesita crear un hash desde un archivo de texto. Para lograr esto, se utiliza la función hash_file. Su sintaxis es la siguiente:
hash_file(string $algo, string $filename, bool $raw_output = false): string
En donde:
- $algo – Es el algoritmo a utilizar
- $filename – Es la URL del archivo a utilizar
- $raw_output – Si es true, será una salida de datos binarios. Caso contrario será en hexadecimal.
Por ejemplo:
file_put_contents('ejemplo.txt', 'Soy un texto random dentro de un archivo');
echo hash_file('sha512', 'ejemplo.txt');
Genera como salida:
119c6809c557b7ff249a04946c5e274e64e56e9fcb1e755ffa55ba83bbf2882f555e41544c
49a6fe3cde51f2fb8f3c9272029c1fd4dced453999ef4cc53ea7a4
Creación de contraseñas fuertes
Pese a todo, las funciones anteriores todavía pueden considerarse débiles ya que por lo general producen como resultado un hash de 60 caracteres o menos. Como resultado, un atacante puede tomar poco tiempo en obtener el string real de la contraseña. Por lo tanto, un hash considerado como fuerte debe por ende tener al menos 60 caracteres.
Existen diversos algoritmos para encriptar considerados fuertes, no obstante en PHP los principales son crypt blowfish y argon2.
Generando una contraseña fuerte
La función que nos sirve para encriptar contraseñas fuertes se llama password_hash. La ventaja de está función contra todas las anteriores es que está diseñada para utilizar cualquier algoritmo de cifrado nuevo que se integre a PHP.
La sintaxis de la función es la siguiente:
password_hash(string $password, integer $algo, array $options = ?): string
El significado de los parámetros es el siguiente:
- $password – Es la contraseña que vamos a cifrar
- $algo – Es el algoritmo a utilizar. Está función soporta los siguientes:
- PASSWORD_DEFAULT: Es el valor por defecto y se adapta al algoritmo más nuevo que se haya integrado a PHP.
- PASSWORD_BCRYPT: Utiliza el algoritmo Crypt Blowfish.
- $options – (Opcional) Es un array de opciones para las contraseñas con blowfish. Aunque en realidad no son muchas opciones, las más interesantes son:
- salt: Utiliza un cadena para generar el hash (obsoleta desde la versión 7 de PHP)
- cost: Determina el tiempo utilizado para calcular el hash, a mayor es el número, mayor tiempo.
Observemos algunos ejemplos de su uso:
$otraClave = "Soy0tr4Clav#";
$res = password_hash($otraClave, PASSWORD_DEFAULT);
echo "Password Default: $res <br />";
$res = password_hash($otraClave, PASSWORD_BCRYPT);
echo "Password Blowfish: $res <br />";
$res = password_hash($otraClave, PASSWORD_BCRYPT,["cost"=>10]);
echo "Blowfish con costo: $res <br />";
Cuyo resultado sería:

Verificando nuestro contraseña fuerte
Para verificar un hash contra su cadena de texto original, tenemos la función password_verify, la cual regresa true si son coincidentes o false si no lo son. Su sintaxis es como sigue:
password_verify(string $password, string $hash): bool
Siendo que:
- $password – El string original para la contraseña
- $hash – El hash generado a raíz del password
Por ejemplo:
if(password_verify($otraClave, $res)) echo "Contraseña válida";
else echo "Contraseña inválida";
Cifrar contraseñas con sal
La función crypt puede generar un hash utilizando el algoritmo Encriptación Standard de Datos (DES) el cual toma un texto de longitud fija y mediante una serie de operaciones sobre otro texto genera el hash. Su longitud es de 64 bits.
La sintaxis básica de esta función es la que sigue:
crypt(string $str, string $salt = ?): string
Siendo sus parámetros:
- $str – Es la cadena para generar el hash
- $salt – Es la cadena necesaria para generar el hash. Aunque es opcional, si no se proporciona por lo generar el hash resultante es bastante débil.
Ejemplo 1: Contraseña generada con una sal semi aleatoria.
$nuevaClave = "HolaS0yUn4NuevaClav#";
$sal1 = "h0l4$0yun4Sa1Cualqu13r%";
$res = crypt($nuevaClave, $sal1);
echo "Contraseña con sal #1: $res <br />";
El hash resultado será el siguiente:
h0Yp180P3efPQ
Ejemplo 2: Contraseña generada con una sal aleatoria única.
$nuevaClave = "HolaS0yUn4NuevaClav#";
$sal2 = "O/jw2XygQa2.LrIT7CFCBQowLowDP6Y";
$res = crypt($nuevaClave, $sal2);
echo "Contraseña con sal #2: $res <br />";
El hash resultante será:
O/fL7w4CmnrgM
Ejemplo 3: Contraseña generada con una sal de 64 bytes totalmente aleatoria y actualizable por cada refresh de página.
$nuevaClave = "HolaS0yUn4NuevaClav#";
$sal3 = bin2hex(random_bytes(64));
$res = crypt($nuevaClave, $sal3);
echo "Contraseña con sal #3: $res <br />";
Dado que es totalmente aleatoria y actualizable gracias a la función random_bytes, aquí hay algunos de los hashes generados:
69MS2WB3dL.C2
33yt6oTy7hPA6
87NTKc.qO9/eE
59Un0xVagLHf6
Sin embargo, en sistemas que soporten más de un algoritmo de cifrado, es posible cambiar el hash al detectarlo con una serie de constantes para los algoritmos más conocidos como STD (CRYPT_STD_DES
), DES extendido (CRYPT_EXT_DES
), MD5 (CRYPT_MD5
), Blowfish (CRYPT_BLOWFISH
), SHA256 (CRYPT_SHA256
) o SHA512 (CRYPT_SHA512
)
Por ejemplo, podemos crear una contraseña bastante fuerte utilizando SHA512 si este es soportado, de lo contrario podemos crear una sal típica de 64 bytes.
if(CRYPT_SHA512){
$microSal = bin2hex(random_bytes(16));
$salPotente = '$6$' . $microSal;
} else $salPotente = bin2hex(random_bytes(64));
$res = crypt($nuevaClave, $salPotente);
echo "Contraseña con sal potente: $res <br />";
Los caracteres $6$ son obligatorios al principio de un salt para SHA512. El resultado puede ser un hash como el que sigue:
Contraseña con sal potente: $6$e7b6b5c6b4e7231b$PgchvNDnQMOVY9tZOZHOVOYfMDSkV/uG0EtOgbl
QuF0ZUoaI9RkgAWRDGWKP1mAG6CR3EnztL9Ff/C8XAp63w0
¡Y ESO ES TODO POR AHORA!
¿Te ha resultado? Déjanos saber en los comentarios aquí abajo, en nuestra cuenta de twitter @cablenaranja7 o en nuestra página de facebook.

Docente, IT Manager, Blogger & Developer. Escribo por diversión, educo por pasión. | Grandstanding is not my thing.