check - php sha password




Come usi bcrypt per le password di hashing in PHP? (6)

Ogni tanto sento il consiglio "Usa bcrypt per memorizzare le password in PHP, bcrypt rules".

Ma cos'è il bcrypt ? PHP non offre alcuna funzione di questo tipo, Wikipedia parla di un'utilità di crittografia dei file e le ricerche Web rivelano solo alcune implementazioni di Blowfish in diverse lingue. Ora Blowfish è disponibile anche in PHP tramite mcrypt , ma come si può aiutare con la memorizzazione delle password? Blowfish è una cifra generica, funziona in due modi. Se può essere crittografato, può essere decodificato. Le password richiedono una funzione di hashing unidirezionale.

Qual è la spiegazione?


È possibile creare un hash unidirezionale con bcrypt utilizzando la funzione crypt() di PHP e passando un appropriato sale Blowfish. Il più importante di tutta l'equazione è che A) l'algoritmo non è stato compromesso e B) si sale correttamente ogni password . Non usare un sale a livello di applicazione; che apre l'intera applicazione per attaccare da un singolo set di tavoli Rainbow.

PHP - Funzione Crypt


La versione 5.5 di PHP avrà il supporto integrato per BCrypt, le funzioni password_hash() e password_verify() . In realtà questi sono solo wrapper attorno alla funzione crypt() , e renderanno più facile usarlo correttamente. Si occupa della generazione di un sale casuale sicuro e fornisce buoni valori predefiniti.

Il modo più semplice per utilizzare queste funzioni sarà:

$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
$isPasswordCorrect = password_verify($password, $existingHashFromDb);

Questo codice cancellerà la password con BCrypt (algoritmo 2y ), genererà un salt casuale dalla sorgente casuale del SO e utilizzerà il parametro di costo predefinito (al momento questo è 10). La seconda riga controlla se la password inserita dall'utente corrisponde a un valore hash già memorizzato.

Se si desidera modificare il parametro di costo, è possibile farlo in questo modo, aumentando il parametro costo di 1, raddoppiando il tempo necessario per calcolare il valore hash:

$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 11));

In contrasto con il parametro "cost" , è meglio omettere il parametro "salt" , perché la funzione fa già del suo meglio per creare un sale crittograficamente sicuro.

Per PHP versione 5.3.7 e successive, esiste un pacchetto di compatibilità , dello stesso autore che ha creato la funzione password_hash() . Per le versioni di PHP precedenti alla 5.3.7 non è supportato crypt() con 2y , l'algoritmo BCrypt sicuro per Unicode. Si potrebbe sostituirlo con 2a , che è la migliore alternativa per le versioni precedenti di PHP.


Otterrete molte informazioni in abbastanza con le tabelle di Rainbow: Che cosa dovete sapere su schemi di password sicura o framework di hashing di password PHP portatile .

L'obiettivo è quello di hash la password con qualcosa di lento, quindi qualcuno che ottiene il tuo database delle password morirà cercando di forzarlo (un ritardo di 10 ms per controllare una password non è niente per te, molto per qualcuno che cerca di forzarlo). Bcrypt è lento e può essere usato con un parametro per scegliere quanto è lento.


Pensiero corrente: gli hash dovrebbero essere il più lento disponibile, non il più veloce possibile. Questo sopprime gli attacchi dei tavoli arcobaleno .

Anche correlati, ma precauzionali: un utente malintenzionato non dovrebbe mai avere accesso illimitato alla schermata di accesso. Per evitare ciò: imposta una tabella di tracciamento degli indirizzi IP che registri ogni hit con l'URI. Se più di 5 tentativi di accesso provengono dallo stesso indirizzo IP in un periodo di cinque minuti, bloccare con una spiegazione. Un approccio secondario è quello di avere uno schema di password a due livelli, come fanno le banche. Mettere un blocco per i guasti al secondo passaggio aumenta la sicurezza.

Riepilogo: rallenta l'aggressore usando lunghe funzioni hash. Inoltre, blocca troppi accessi all'accesso e aggiungi un secondo livello di password.


Quindi, vuoi usare bcrypt? Eccezionale! Tuttavia, come in altre aree della crittografia, non dovresti farlo tu stesso. Se hai bisogno di preoccuparti di qualcosa come la gestione delle chiavi, la memorizzazione di sali o la generazione di numeri casuali, stai sbagliando.

La ragione è semplice: è così banalmente facile rovinare tutto . Infatti, se guardi quasi ogni pezzo di codice in questa pagina, noterai che sta violando almeno uno di questi problemi comuni.

Face It, la crittografia è difficile.

Lascia fare agli esperti. Lascialo per le persone che hanno il compito di mantenere queste librerie. Se hai bisogno di prendere una decisione, stai sbagliando.

Invece, basta usare una libreria. Diversi esistono in base alle vostre esigenze.

biblioteche

Ecco una ripartizione di alcune delle API più comuni.

API PHP 5.5 - (disponibile per 5.3.7+)

A partire da PHP 5.5, viene introdotta una nuova API per le password di hashing. C'è anche una libreria di compatibilità shim mantenuta (da me) per 5.3.7+. Questo ha il vantaggio di essere un'implementazione peer-reviewed e di semplice utilizzo.

function register($username, $password) {
    $hash = password_hash($password, PASSWORD_BCRYPT);
    save($username, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    if (password_verify($password, $hash)) {
        //login
    } else {
        // failure
    }
}

In realtà, ha lo scopo di essere estremamente semplice.

risorse:

Zend \ Crypt \ Password \ Bcrypt (5.3.2+)

Questa è un'altra API simile a quella di PHP 5.5, e ha uno scopo simile.

function register($username, $password) {
    $bcrypt = new Zend\Crypt\Password\Bcrypt();
    $hash = $bcrypt->create($password);
    save($user, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    $bcrypt = new Zend\Crypt\Password\Bcrypt();
    if ($bcrypt->verify($password, $hash)) {
        //login
    } else {
        // failure
    }
}

risorse:

PasswordLib

Questo è un approccio leggermente diverso per l'hashing delle password. Piuttosto che semplicemente supportare bcrypt, PasswordLib supporta un gran numero di algoritmi di hashing. È utile soprattutto in contesti in cui è necessario supportare la compatibilità con sistemi legacy e disparati che potrebbero essere al di fuori del proprio controllo. Supporta un gran numero di algoritmi di hashing. Ed è supportato 5.3.2+

function register($username, $password) {
    $lib = new PasswordLib\PasswordLib();
    $hash = $lib->createPasswordHash($password, '$2y$', array('cost' => 12));
    save($user, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    $lib = new PasswordLib\PasswordLib();
    if ($lib->verifyPasswordHash($password, $hash)) {
        //login
    } else {
        // failure
    }
}

Riferimenti:

  • Codice sorgente / documentazione: GitHub

PHPASS

Questo è un livello che supporta bcrypt, ma supporta anche un algoritmo abbastanza potente che è utile se non si ha accesso a PHP> = 5.3.2 ... In realtà supporta PHP 3.0+ (anche se non con bcrypt).

function register($username, $password) {
    $phpass = new PasswordHash(12, false);
    $hash = $phpass->HashPassword($password);
    save($user, $hash);
}

function login($username, $password) {
    $hash = loadHashByUsername($username);
    $phpass = new PasswordHash(12, false);
    if ($phpass->CheckPassword($password, $hash)) {
        //login
    } else {
        // failure
    }
}

risorse

Nota: non utilizzare le alternative PHPASS che non sono ospitate su openwall, sono progetti diversi !!!

Informazioni su BCrypt

Se si nota, ognuna di queste librerie restituisce una singola stringa. Questo a causa di come BCrypt funziona internamente. E ci sono un sacco di risposte al riguardo. Ecco una selezione che ho scritto, che non copierò / incollerò qui, ma link a:

Incartare

Ci sono molte scelte differenti. Quale scegli dipende da te. Tuttavia, mi raccomando caldamente di utilizzare una delle librerie di cui sopra per la gestione di questo per voi.

Di nuovo, se stai usando crypt() direttamente, probabilmente stai facendo qualcosa di sbagliato. Se il tuo codice usa direttamente hash() (o md5() o sha1() ), stai quasi sicuramente facendo qualcosa di sbagliato.

Basta usare una biblioteca ...


Un'alternativa è usare lo scrypt, progettato specificamente per essere superiore a bcrypt di Colin Percival nel suo articolo . C'è un'estensione PHP scrypt in PECL . Idealmente questo algoritmo verrebbe inserito in PHP in modo che potesse essere specificato per le funzioni password_ * (idealmente come "PASSWORD_SCRYPT"), ma non è ancora lì.





bcrypt