Gestione delle password con PHP

3 marzo 2017

È buona norma aumentare il livello di sicurezza delle nostre applicazioni evitando di memorizzare le password in chiaro nel database. Una buona pratica consiste nel memorizzare, invece, un hash da cui si può verificare che la password inserita dall'utente sia corretta.

MD5 e SHA1

Sino a qualche anno fa le strategie di hashing più diffuse utilizzavano la codifica in MD5 o in SHA1. Ad esempio:

$password = 'LaM1aPassW0rd';
$hash = md5($password); //b33a0446525f0e11e91bd268dbbdfdc3
$hash = sha1($password); //814486c99c198b99d7d3e8a585d8b6be324b7177

Il vantaggio di tali soluzioni è che sono "one-way", cioè non esiste un algoritmo capace di decodificarli. Tale strategia non si rivela però molto efficace dato che online esistono moltissimi tool che attraverso delle rainbow table sono in grado di restituire la stringa iniziale partendo dall'hash.

Strategie alternative consistevano nel combinare tra di loro o applicare più volte tali algoritmi alla stringa. Ad esempio:

$password = 'LaM1aPassW0rd';
$hash = md5(md5($password);
$hash = md5(sha1($password);

Un'altra strategia, applicata anche insieme a quelle già viste, consiste nel combinare un salt alla password, cioè una stringa di caratteri casuali che dovrebbe aumentare la complessità.

$password = 'LaM1aPassW0rd';
$salt = '1dh3(3@2';

$hash = md5($password . $salt);

Tutte queste tecniche di codifica continuano ad avere un problema alla base: l'algoritmo di codifica è veloce, questo significa che un malintenzionato può eseguire miliardi di tentativi al secondo su una singola CPU. In termini più semplici, per quanto ci possiamo impegnare a rendere complesso l'hash, resta comunque probabile che si riesca a risalire alla password originale in tempi non molto elevati.

La funzione crypt()

Un'alternativa molto più sicura in PHP consiste nell'utilizzare la funzione crypt().

La funzione prende in ingresso due parametri:

  1. $str: la stringa da criptare.
  2. $salt: il salt da applicare. Questo campo è opzionale ma altamente consigliato per evitare di generare password deboli.

Tale funzione utilizza l'algoritmo standard DES di Unix oppure, in base al tipo di salt, uno tra quelli disponibili nel sistema tra:

Algoritmo Descrizione
CRYPTSTDDES Standard basato su DES con chiave di due caratteri.
CRYPTEXTDES Estensione basata su DES con chiave di nove caratteri.
CRYPT_MD5 Crittografia basata su MD5 con 12 caratteri di chiave inizianti con $1$.
CRYPT_BLOWFISH Crittografia Blowfish con 16 caratteri di chiave inizianti con $2$ o $2a$.
CRYPT_SHA256 Crittografia basata su SHA-256 con 16 caratteri di chiave inizianti con $5$.
CRYPT_SHA512 Crittografia basata su SHA-512 con 16 caratteri di chiave inizianti con $6$.
$password = 'LaM1aPassW0rd';
echo 'Standard DES: ' . crypt($password, 'rl') . "\n";
echo 'Extended DES: ' . crypt($password, '_J9..rasm') . "\n";
echo 'MD5:  ' . crypt($password, '$1$rasmusle$') . "\n";
echo 'Blowfish: ' . crypt($password, '$2a$07$usesomesillystringforsalt$') . "\n";
echo 'SHA-256:  ' . crypt($password, '$5$rounds=5000$usesomesillystringforsalt$') . "\n";
echo 'SHA-512:  ' . crypt($password, '$6$rounds=5000$usesomesillystringforsalt$') . "\n";

Gli output che otterremo sono simili ai seguenti:

Standard DES: rlrilO6oNxQzw
Extended DES: _J9..rasmvAavwwHGzfY
MD5:  $1$rasmusle$YumKbTCImTJsTsgYeybAW0
Blowfish: $2a$07$usesomesillystringfore0frKquhsqiIddYDH.rpL9GGLE4ZN1lu
SHA-256:  $5$rounds=5000$usesomesillystri$xoDuebqNnfT3MOdczgqISdPxZ2C91n550ToQbY7LeP5
SHA-512:  $6$rounds=5000$usesomesillystri$ih83lc2hDlh5FrDrhPdbnhzGTWI79lquzan21cOOOgRGpX9e/R21pK6HNU1JYLtqh7Xr2na51P/Ibpj2AQ1TW0

Una volta che la password è stata codificata e memorizzata, per assicurarci che l'utente stia tentando l'accesso con la password corretta abbiamo bisogno di una seconda funzione: hash_equals(). Essa prende in ingresso due parametri:

  1. l'hash della password attesa.
  2. l'hash della password immessa dall'utente.

hash_equals() ci restituirà un booleano in base al risultato della verifica. Vediamo un esempio:

$password = 'LaM1aPassW0rd'; //password valida
$hashedPassword = crypt($password, '$2a$07$usesomesillystringforsalt$'); //hash memorizzato nel database

$userPassword = 'LaM1aPassW0rd'; //password inserita dall'utente nel login
$hashedUserPassword = crypt($userPassword, '$2a$07$usesomesillystringforsalt$');

if(hash_equals($hashedPassword, $hashedUserPassword)) {
    echo "Accesso effettuato con successo";
} else {
    echo "La password inserita non è corretta";
}

Sicuramente la funzione crypt ci consente di avere degli hash molto più sicuri rispetto agli esempi iniziali. Di contro però risulta piuttosto macchinosa da utilizzare e molto incline a errori di programmazione.

Tutte le lezioni

1 ... 35 36 37 ... 49

Se vuoi aggiornamenti su Gestione delle password con PHP inserisci la tua e-mail nel box qui sotto:
Tags:
 
X
Se vuoi aggiornamenti su Gestione delle password con PHP

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy