Cifrando passwords con php
Tags: php, spanish, developer, webdev
Published: 2021-03-15 22:15:15

Hola, en esta oportunidad les vengo a mostrar lo simple que puede ser cifrar contraseñas con PHP.

Yo tego una base de datos donde tengo una tabla llamada usuarios, en ella tenemos los siguientes campos:

- email
- password
- admin(booleano)
- id

Lo que vamos a utilizar para poder cifrar y comparar las contraseñas hasheadas son las funciones:

- password_hash()
- password_verify()

Estas API's que trae por defecto PHP en su versión 5.3.7 y versiones posteriores nos permite hashear las contraseñas agregando salts, pero...

##¿Qué es una sal (salt)? Según la documentación de PHP:

    
Una sal criptográfica es un dato que se utiliza durante el proceso de hash para eliminar la posibilidad de que el resultado pueda buscarse a partir de una lista de pares precalculados de hash y sus entradas originales, conocidas como tablas rainbow.

Es decir, una sal es un pequeño dato añadido que hace que los hash sean significantemente más difíciles de crackear. Existe un gran número de servicios online que ofrecen grandes listas de códigos hash precalculados, junto con sus datos de entrada originales. El uso de una sal hace muy difícil o imposible encontrar el hash resultante en cualquiera de estas listas.

password_hash() creará una sal aleatoria si no se proporciona una, siendo esta generalmente la estrategia más sencilla y segura.

Pasemos al código, tengo una función que me permite registrar usuarios en la base de datos enviando las querys a través de PDO:

```php
    public function registro($email, $password){
        include_once('database/Connect.php');
        $pass = password_hash($password, PASSWORD_DEFAULT);
        $stmt = $db->prepare("INSERT INTO usuarios (email, password, admin, id) values (?, ?, true, 2020202)");
        $stmt->execute([$email, $pass]);
    }
```

Lo que hace esta función es conectarse a la base de datos a través de la conexión declarada en la segunda línea, una vez conectado lo que hacemos es tomar el password que agarramos por el parámetro $password y lo hasheamos con la opción por default que trae password_hash, que es muy segura.

Después de esto procedemos a enviarle los datos a la tabla a través de una consulta preparada, esto se ejecuta y se guardan los datos en la db de la siguiente manera:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cu4liu3czrjbnxspmf3r.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ceqz7t6iqjojpb42ioe1.png)

Como podemos ver los datos se guardan correctamente, ahora lo que tenemos que hacer es comparar el password con el hash para ver si es correcto y el usuario puede iniciar sesión.

Tenemos una función que hace eso por nosotros:

```php
    public function login($email, $password){
        include_once('database/Connect.php');
        $stmt = $db->prepare("SELECT email, password, admin FROM usuarios where email = ?");
        $stmt->execute([$email]);
        $count = $stmt->rowCount();
        $data = $stmt->fetch(PDO::FETCH_OBJ);
        if($count){
            if(password_verify($password, $data->password)){
                if($data->admin == 1){
                    session_start();
                    $_SESSION['admin'] = 'admin';
                    header('Location: http://localhost/prueba/panel');
                    exit();
                }
            }
        }
        else{
            echo 'Error: Usuario no registrado';
        }
    }
```

Lo que hacemos acá es recibir los parámetros $email y $password, con email buscamos si adentro de la tabla usuarios existe un email que coincida con el que recibimos, en el caso de que exista vamos a comprobar con la función password_verify() si el password que recibimos coincide con el hash que tenemos guardado en la base de datos, así que primero le pasamos el password y por último el hash que tenemos guardado en la db. Ahora, en el caso de que el password coincida y que además el usuario tenga en la columna admin el valor true o 1 vamos a crear una nueva sesión de administrador y vamos a redireccionar hacia el panel de administración, y sino es así, vamos a enviar un error.


![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uyk2bq668gin08gx47l2.png)