La nueva API para codificar contraseñas de PHP 5.5

Sólo han pasado seis meses desde el lanzamiento de PHP 5.4 pero ya se está trabajando intensamente en la próxima gran versión PHP 5.5. A través de esta noticia de Hacker News nos acabamos de enterar de que ya ha sido completada la nueva API para codificar contraseñas con PHP.

Si programas aplicaciones Symfony2, seguramente tu configuración de seguridad es parecida a lo siguiente:

# app/config/security.yml
security;    
    encoders:
        Cupon\UsuarioBundle\Entity\Usuario: { algorithm: sha512, iterations: 10 }
        Cupon\TiendaBundle\Entity\Tienda:   { algorithm: sha512, iterations: 10 }
        Symfony\Component\Security\Core\User\User: sha512

La opción sha512 hace que las contraseñas se codifiquen 5.000 veces seguidas con el algoritmo sha512 utilizando en cada pasada el resultado de la anterior y codificando el resultado final (conocido como hash) con Base64. Por otra parte, las contraseñas también utilizan un valor aleatorio conocido como salt y que dificulta descubrir una contraseña a partir de su hash.

Aunque por comodidad en ocasiones se comete el error de utilizar valores tan simples como md5(rand()), algunos bundles como FOSUserBundle eligen buenos valores aleatorios:

$this->salt = base_convert(sha1(uniqid(mt_rand(), true)), 16, 36);

Todo esto podría cambiar radicalmente con la nueva API de PHP para codificar contraseñas. Al parecer, codificar contraseñas con sha512() no es suficientemente seguro, ya que es un algoritmo muy rápido que lo convierte en un blanco fácil de los ataques por fuerza bruta.

La nueva propuesta se basa en bcrypt() e implementa un algoritmo diseñado a propósito para que sea lento, lo que hace inviables los ataques de fuerza bruta. A partir de ahora, para codificar una contraseña sólo tendrás que ejecutar la siguiente función PHP:

$hash = password_hash($password, PASSWORD_DEFAULT);

Aunque el valor $hash devuelto no es un objeto, contiene en su interior tanto la contraseña codificada como el valor salt generado aleatoriamente. La opción PASSWORD_DEFAULT indica que se utilicen las opciones por defecto (algoritmo bcrypt y un coste de computación igual a 10). Puedes cambiar todas estas opciones para adaptarlas a tus necesidades:

$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);

Y para comprobar si la contraseña proporcionada por un usuario es válida, tan sólo debes realizar una llamada a otra función:

// $password es lo que ha introducido el usuario
// $hash es lo que guardamos en la base de datos
if (password_verify($password, $hash)) {
    // contraseña correcta
} else {
    // contraseña incorrecta
}

Si quieres conocer más detalles sobre esta nueva API, puedes consultar el documento Adding simple password hashing API.

Comentarios

  1. mmmm... ya espero con ancias esta nueva forma de codificación en php, aligera mucho las cosas..

    Francisco Mora el 1 de febrero de 2013, 2:55:55

Este artículo ya no permite añadir más comentarios.
¿Por qué? Los artículos cierran sus comentarios automáticamente unos meses después de su publicación para asegurar que estos sigan siendo relevantes.

Publicada el

13 de septiembre de 2012

Etiquetas

Proyectos Symfony destacados

La forma más sencilla de generar el backend de tus aplicaciones Symfony. Ver más

Síguenos en @symfony_es para acceder a las últimas noticias.