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
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 usarPASSWORD_DEFAULTperquè 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
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
truesi la contrasenya coincideix amb el hash, ofalseen 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
$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
// 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():
-
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_DEFAULTactual del sistema. -
Si cal actualitzar, es genera un nou hash amb la configuració més recent i es substitueix l'antic a la base de dades.
// 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.";
}
}