Ves al contingut principal

Hash password PHP

password_hash(): Creació del hash

La funció password_hash() és la responsable de generar el hash criptogràfic d'una contrasenya.

Definició i propòsit

  • Propòsit: Transformar una contrasenya en text clar en una cadena de caràcters irreversible (hash). Aquesta és la cadena que s'emmagatzema a la base de dades.

  • Seguretat Integrada: Està dissenyada específicament per a l'emmagatzematge de contrasenyes, ja que utilitza algorismes lents com Bcrypt per defecte. Aquesta lentitud intencionada fa que els atacs de força bruta siguin molt costosos en termes de temps i recursos.

  • Salt Aleatòria: La funció genera i incorpora automàticament una sal (salt) criptogràfica única al hash resultant. Això protegeix contra els atacs de Rainbow Tables (taules precalculades).

Sintaxi

PHP

password_hash(string $password, int $algo, array $options = []): string
  • $password: La contrasenya en text clar de l'usuari.

  • $algo: L'algoritme de hashing a utilitzar. Es recomana usar PASSWORD_DEFAULT perquè PHP utilitzi l'algoritme més segur i actual disponible (actualment Bcrypt).

  • Retorn: Retorna la cadena de hash completa (que inclou l'algoritme, el cost i la sal).

password_verify(): Validació del hash

La funció password_verify() és la funció de verificació que es fa servir quan un usuari intenta iniciar sessió.

Definició i propòsit

  • Propòsit: Comprovar si una contrasenya de text clar donada coincideix amb un hash emmagatzemat.

  • Procés de Validació: La funció agafa la contrasenya que ha introduït l'usuari i extreu automàticament la sal i la configuració (cost) del hash emmagatzemat. Llavors, calcula un nou hash utilitzant exactament els mateixos paràmetres i el compara caràcter per caràcter amb el hash emmagatzemat.

  • Seguretat a l'Execució: Està protegida contra atacs de temps, ja que la comparació del hash es fa de manera que el temps d'execució sigui constant, independentment de si la contrasenya és correcta o no.

Sintaxi

PHP

password_verify(string $password, string $hash): bool
  • $password: La contrasenya en text clar introduïda per l'usuari.

  • $hash: El hash emmagatzemat a la base de dades.

  • Retorn: Retorna true si la contrasenya coincideix amb el hash, o false en cas contrari.

La combinació d'aquestes dues funcions garanteix que les contrasenyes dels vostres usuaris mai s'emmagatzemin com a text clar i es verifiquin de la manera més segura i resistent als atacs de cracking de contrasenyes.

Exemple: obtenir un hash en PHP

La funció recomanada en PHP és password_hash(). Aquesta funció utilitza per defecte l'algoritme Bcrypt (o un algoritme més segur si està disponible, com es defineix a PASSWORD_DEFAULT), genera una sal (salt) aleatòria i la incorpora al hash final.

PHP

<?php
$contrasenya_clara = "LaMevaContrasenyaSecreta123";

// 1. Crear el hash de forma segura
// PASSWORD_DEFAULT assegura que s'utilitza l'algoritme més fort disponible (actualment Bcrypt).
$hash_segur = password_hash($contrasenya_clara, PASSWORD_DEFAULT);

echo "Contrasenya clara: " . $contrasenya_clara . "\n";
echo "Hash segur: " . $hash_segur . "\n";

// El hash_segur resultant conté la informació de l'algoritme, el cost i la sal.
?>

Emmagatzemar hash a la base de dades

El resultat de la funció password_hash() ($hash_segur) és el que s'ha d'emmagatzemar a la base de dades.

  • Tipus de Dades: El hash generat per password_hash() sol tenir una longitud de 60 caràcters (per a Bcrypt). Per seguretat futura o canvis d'algoritme, es recomana utilitzar un camp de text de longitud variable (com VARCHAR o CHAR) d'una mida generosa, per exemple, 255 caràcters.

  • Contingut del Hash: El hash resultant és una cadena que conté:

    • L'identificador de l'algoritme (p. ex., $2y$ per Bcrypt).

    • El paràmetre de cost (o iteracions).

    • La sal (salt) única per a aquesta contrasenya.

    • El propi valor hash.

Nota: Amb password_hash(), no cal emmagatzemar la sal per separat. La sal i la configuració s'incorporen automàticament al hash generat.

Validació a PHP: password_verify()

Quan un usuari intenta iniciar sessió, no cal tornar a generar el hash ni extreure manualment la sal. La funció password_verify() gestiona tot el procés automàticament i de forma segura. Aquesta funció compara la contrasenya que introdueix l'usuari amb el hash emmagatzemat.

PHP

<?php
// Suposem que l'usuari intenta iniciar sessió
$contrasenya_introduida = "LaMevaContrasenyaSecreta123";
// Aquest valor s'extreu de la base de dades
// Exemple de hash segur
$hash_emmagatzemat = '$2y$10$iKU5Fz0GqA1uN6H7K8L9M0O1P2Q3R4S5T6U7V8W9X0Y1Z2a3b4c5d6e7f8g9h0i1j2k'; 

// 2. Verificar la contrasenya
if (password_verify($contrasenya_introduida, $hash_emmagatzemat)) {
    echo "Contrasenya correcta! Accés permès. ";
    // Si la contrasenya és correcta, podeu verificar si el hash necessita ser actualitzat
    if (password_needs_rehash($hash_emmagatzemat, PASSWORD_DEFAULT)) {
        // (Opcional, però recomanat) Vegeu la secció 4
    }
} else {
    echo "Contrasenya incorrecta. Accés denegat. ";
}
?>

Actualització del hash (Re-hashing)

Aquesta és una pràctica de seguretat avançada que permet al vostre sistema millorar la seguretat de les contrasenyes automàticament, sense demanar a l'usuari que canviï la seva contrasenya.

S'utilitza la funció password_needs_rehash():

  1. Verifica si l'algoritme de hash emmagatzemat o les seves configuracions (p. ex., el cost o el nombre d'iteracions) estan desactualitzats respecte a la configuració PASSWORD_DEFAULT actual del sistema.

  2. Si cal actualitzar, es genera un nou hash amb la configuració més recent i es substitueix l'antic a la base de dades.

PHP

// Dins de la verificació d'accés (pas 3):
if (password_verify($contrasenya_introduida, $hash_emmagatzemat)) {
    // La contrasenya és correcta, ara comprovem si el hash és obsolet
    if (password_needs_rehash($hash_emmagatzemat, PASSWORD_DEFAULT)) {
        $nou_hash = password_hash($contrasenya_introduida, PASSWORD_DEFAULT);
        // Actualitzar el hash a la base de dades amb $nou_hash
        echo " | Hash actualitzat correctament a la BDD.";
    }
}