Autonomía digital y tecnológica

Código e ideas para una internet distribuida

Sistema seguro de registro y conexión de usuarios en PHP: password_hash, password_verify, cookie de sesión y el concepto de pepper

Imago voragine.net

La mayoría de las veces que se necesita un sistema de usuarios se usa el del CMS o el framework que se esté usando para desarrollar. Para las pocas veces que no sea el caso, o para quien quiera aprender cómo funciona un sistema de registro e inicio de sesión de usuarios a más bajo nivel, aquí algunas pistas de cómo construir uno de manera segura usando PHP.

En este caso lo voy a hacer usando las funciones password_hash y password_verify.

Para qué sirve password_hash y password_verify

La idea es la siguiente: un usuario utiliza un formulario para registrarse en el sitio web. Se almacena su nombre de usuario y su contraseña en base de datos. Para ello se usa password_hash. password_hash genera un hash, una secuencia de caracteres según un algoritmo de cifrado, a partir de la contraseña que se le suministre. password_hash genera cada vez una secuencia distinta aun a partir de la misma contraseña. Esta idea es importante.

Para asegurarse de alojar correctamente el hash en base de datos hay que hacerlo en un registro CHAR(60). Si la extensión es menor, el hash se almacenará incompleto.

Una vez registrado ese usuario utiliza otro formulario para iniciar sesión con su nombre de usuario y su contraseña. Para verificar la contraseña se usa password_verify. password_verify permite comprobar autenticidad de un hash con el password que se le suministre y así decidir que el password es válido o no. password_verify es capaz de encontrar la correspondencia entre cualquiera de los múltiples hash que puede generar password_hash (recuerdo que cada vez que se ejecuta, aún a partir de la misma contraseña, genera uno diferente) con la contraseña que se le suministre. Esta el la magia: la relación no es única.

Qué es un pepper

Cuando se trata de crear un sistema seguro en definitiva la idea es que para encontrar la contraseña haya que invertir mucho tiempo y energía. Si el tiempo y la energía necesarios son suficientemente elevados, el sistema es en la práctica seguro. Este grado adicional de complejidad lo aporta el concepto de pepper, haciendo que un sistema basado en password_hash y password_verify sea difícil de craquear. Un pepper es un autentificador (token) secreto que sirve para hacer prácticamente imposible que tenga éxito un ataque por fuerza bruta.

El pepper hay que guardarlo en un lugar seguro, claro. Se recomienda no guardarlo en la base de datos que aloja los hashs porque vale justamente para ponerle las cosas difíciles a un atacante que ha conseguido acceso a la base de datos. En este caso, aún teniendo el hash contenido en la base de datos, no tendrá el pepper. El pepper se puede alojar en un archivo de configuración.

Si al código anterior que permitía registrar un usuario le añadimos la capa pepper quedaría algo como lo que sigue. Supongamos que el pepper lo alojamos en el archivo de configuración conf.php y que lo rescatamos con la función get_pepper():

Y ahora al que permitía darle acceso a la web:

Mantener al usuario conectado durante toda una sesión usando cookies

Una vez que el usuario está registrado y ha iniciado sesión conviene que el sitio web no le pida introducir su contraseña conforme va navegando por él, con cada cambio de página web. Para mantener al usuario conectado se puede usar una cookie.

De nuevo, al código anterior le vamos a añadir esta nueva capa de la cookie, a la que vamos a llamar «Access»:

A la hora de alojar una cookie en el navegador del usuario es conveniente tomar algunas medidas de seguridad.

No hay comentarios

    • Por German

    Muy buen aporte con password_hash, ya lo implemente en mi pagina, pero como dicen no hay seguridad al 100%, una pregunta? es la mejor técnica actualmente o hay otra mejor que esta? hablando para php 7.3

    1. Hola German,

      efectivamente no hay sistema cien por cien seguro. De lo que yo he podido leer, en PHP es de lo más seguro. Pero tampoco soy yo un experto en seguridad.

  1. Incredible

Dejar un comentario

*
*

 

No hay trackbacks