InicioCiencia EducacionSeguridad en PHP #1: Contraseñas!
Seguridad en PHP #1: Contraseñas!

Bienvenidos! Decidí dividir el post general de seguridad en varios ya que se alargo mucho y quedaba una pared de texto. En los siguientes días voy a estar posteando sobre CSRF, XSS e inyecciones SQL.

Hoy vamos ver un tema extremadamente importante para proteger a tus usuarios: como almacenar contraseñas de una manera criptográficamente segura. Desafortunadamente se tienen muy malas practicas sobre el tema hoy en día, hago este post para tratar de explicarles que es seguro y que no.

Antes de empezar, voy a aclarar algunos términos por las dudas:
BD: Base de datos, la mayoría de ustedes, como yo, debe usar MySQL.
Hashear: generar clave de orden unidireccional (solo se encripta, no se puede desencriptar).
Hash: el resultado del algoritmo criptografico al hashear una cadena de texto.
Salt: una cadena de texto que se agrega a la contraseña (en este caso antes y durante el hasheo) para prevenir ciertos tipos de ataques.

PHP

criptografia

Regla #1 y la mas importante de todas: nunca, nunca, nunca, nunca JAMAS guardar las contraseñas tal y como la escribe el usuario en la BD.

Esto lo aprendió la conocida pagina Reddit hace un tiempo, a comienzos del 2007.
Robaron un dispositivo que tenia adentro parte de una BD y dentro de ella estaban los datos de miles de usuarios, junto con su contraseña sin hashear.
Pero porque, que razón podrían tener para guardar así las contraseñas? Para poder hacer las cosas mas simples para el usuario. Si se olvidaba de la contraseña, el sistema simplemente se la enviaba devuelta a través de su correo, no había necesidad de establecer una nueva.
Doble mala idea, no hashear contraseñas y ademas de todo mandarlas por mail.

Claro esta que después del incidente los usuarios tuvieron que cambiar su contraseña en todos lados, ya que el ladrón tenia la combinación de mail y contraseña. También empezaron a hashearlas, como debe ser.

contrasenas

usuarios


Ya se lo que estas pensando: "Las contraseñas de mi pagina están perfectamente bien hasheadas con MD5/SHA1!".
Bueno.. no, MD5 y SHA1 fueron creados en 1992 y 1995 respectivamente, por lo cual esta bastante claro lo obsoletos que son. Arriba de eso, ambos fueron diseñados para ser computacionalmente "baratos" (se generan rápido) entonces son susceptibles a ataques de "fuerza bruta" con simples tarjetas de video, que generan cientos de miles de hashes por segundo.

Esto nos lleva a la Regla #2: nunca, nunca, nunca JAMAS usar MD5 o SHA1 para hashear contraseñas.

Base de Datos

Entonces la pregunta es, después de todo el discurso, como carajo las hasheo?
Desde PHP 5.5 hay una función justamente diseñada para esto: password_hash.
Si no tenes PHP 5.5 no te preocupes, de 5.3.7 para adelante lo podes usar igual incluyendo esta biblioteca: Password Compat en GitHub

Lo bueno de esta función es que aunque los usuarios tengan exactamente la misma contraseña el hash de cada uno va a ser completamente distinto. Esto se debe a que el sistema genera una salt aleatoria para cada hash.

Vamos a usarla de la siguiente manera:
<?php
$contra 
'Hola1234';
$salt = 'CualquierCosaDeMasDe32CaracteresDeLargo';
$cost = 10;
$contraBD = password_hash($salt . $contra, PASSWORD_DEFAULT, array('cost' => $cost));


$contra: La contraseña del usuario a hashear.
$salt: 32 o mas caracteres aleatorios. Protege la contraseña contra ciertos tipos de ataques. Nunca se cambia después de registrado al menos 1 usuario, se usa la misma para todas las contraseñas. Si la cambias en algún punto los usuarios van a tener que cambiar la contraseña y re-hashearla con la "salt" nueva.
$cost: Cuantas veces la función va a ser ejecutada sobre el resultado de la anterior. Cuanto mas grande mas demora en generarse la contraseña. Es bueno para los ataques de "fuerza bruta" ya que cada contraseña demora alrededor de 1/2 segundo en generarse, pudiendo obtener solo 2 hashes por segundo. Recomiendo dejarla en 10 porque si no demora demasiado. En el futuro si es necesario se puede aumentar sin problemas, las contraseñas viejas van a seguir sirviendo.
PASSWORD_DEFAULT le dice al sistema que elija la función de hash mas segura. Recomiendo dejarlo asi, de esta manera si en el futuro se implementa un metodo mas seguro cambia a ese automáticamente y aun así las contraseñas viejas siguen sirviendo.

Esto nos devolvería la función si la usamos con esos datos ($contraBD), debe ser guardado en la BD tal y como esta:
encriptar


Como pueden ver, cada sección del hash representa algo distinto. Estos datos van a ser usados en la siguiente función que les voy a mostrar.

seguridad

Siendo muy considerados los desarrolladores de PHP, incluyeron también una función para fácilmente verificar la contraseña cuando un usuario se vaya a logear: password_verify.

Se usaria de esta manera:
<?php
$contra 
= 'Hola1234';
$salt = 'CualquierCosaDeMasDe32CaracteresDeLargo';
$contraBD = '$2y$10$XmgLsN2pnmi1/.wN47ZLkeEJBuBhS09NJ9radoSOGKFV9Zosz4euu';
password_verify($salt . $contra, $contraBD);


$contra: La contraseña que escribe el usuario cuando se va a loguear.
$salt: IGUAL a $salt definida cuando usamos password_hash.
$contraDB: El hash que devolvió la función password_hash antes, hay que conseguirlo desde la BD donde deberíamos haberlo guardado anteriormente.

Esto devolvería true si el hash y la contraseña coinciden, en el caso de que no devuelve false. Como dije anteriormente, muy útil para el logueo, ya que se puede usar un simple if con la función adentro.

hash


Asi termina el post, espero haber sido de ayuda.
Gracias por pasar y leer, aca tenes tu premio:

(Cualquier duda no tengas miedo de preguntar en los comentarios.)

hasing
Datos archivados del Taringa! original
146puntos
188visitas
0comentarios
Actividad nueva en Posteamelo
0puntos
13visitas
0comentarios
Dar puntos:

Dejá tu comentario

0/2000

Autor del Post

G
Glitched🇦🇷
Usuario
Puntos0
Posts7
Ver perfil →
PosteameloArchivo Histórico de Taringa! (2004-2017). Preservando la inteligencia colectiva de la internet hispanohablante.

CONTACTO

18 de Septiembre 455, Casilla 52

Chillán, Región de Ñuble, Chile

Solo correo postal

© 2026 Posteamelo.com. No afiliado con Taringa! ni sus sucesores.

Contenido preservado con fines históricos y culturales.