SHA1 vs md5 vs SHA256: quale utilizzare per un login PHP?


133

Sto effettuando un login php e sto cercando di decidere se usare SHA1 o Md5 o SHA256 di cui ho letto in un altro articolo di StackOverflow. Qualcuno di loro è più sicuro di altri? Per SHA1 / 256, uso ancora un sale?

Inoltre, è un modo sicuro per archiviare la password come hash in mysql?

function createSalt()
{
    $string = md5(uniqid(rand(), true));
    return substr($string, 0, 3);
}

$salt = createSalt();

$hash = sha1($salt . $hash);


Vedi anche questa risposta e leggi la sezione relativa all'hash delle password.
Ja͢ck

Risposte:


110

Né. Si dovrebbe usare bcrypt. Gli hash che hai citato sono tutti ottimizzati per essere veloci e facili sull'hardware, e quindi crackarli condividono le stesse qualità. Se non hai altra scelta, almeno assicurati di usare un lungo sale e ripetere l'hash più volte.

Utilizzo di bcrypt in PHP 5.5+

PHP 5.5 offre nuove funzioni per l'hash della password . Questo è l'approccio consigliato per l'archiviazione delle password nelle moderne applicazioni Web.

// Creating a hash
$hash = password_hash($password, PASSWORD_DEFAULT, ['cost' => 12]);
// If you omit the ['cost' => 12] part, it will default to 10

// Verifying the password against the stored hash  
if (password_verify($password, $hash)) {
    // Success! Log the user in here.
}

Se stai usando una versione precedente di PHP, dovresti davvero aggiornare , ma fino a quando non lo fai puoi usare password_compat per esporre questa API.

Inoltre, ti preghiamo di password_hash()generare il sale per te. Utilizza un CSPRNG .

Due avvertenze di criptovaluta

  1. Bcrypt troncerà silenziosamente qualsiasi password più lunga di 72 caratteri.
  2. Bcrypt verrà troncato dopo qualsiasi NULcarattere.

( Prova del concetto per entrambi gli avvertimenti qui.)

Potresti essere tentato di risolvere il primo avvertimento eseguendo il pre-hashing delle tue password prima di eseguirle tramite bcrypt , ma ciò potrebbe causare la prima esecuzione dell'applicazione nel secondo.

Invece di scrivere il proprio schema, utilizzare una libreria esistente scritta e / o valutata da esperti di sicurezza.

TL; DR - Usa bcrypt .


1
inoltre, sono molto nuovo in questo: sha1, sha256 e md5 sono tutti gli "hash" a cui ti riferisci?
Tony Stark,

3
Sì. Mi riferisco a SHA1, SHA256 e MD5 e ad una serie di altri hash ottimizzati per la velocità. Non si desidera utilizzare un hash ottimizzato per la velocità per proteggere una password. Ci sono molti buoni articoli che parlano del perché, e questo mi piace in particolare: chargen.matasano.com/chargen/2007/9/7/…
Johannes Gorset,

4
È incluso nella funzione "crypt" da PHP 5.3. Se hai una versione precedente, esaminerei il framework "phpass" per la prossima cosa migliore.
Johannes Gorset,

3
@Stanislav Palatnik SHA512 è una buona alternativa. Non fraintendetemi; Non sto dicendo che un hash SHA512 allungato e salato sia insicuro. È sicuro. Anche così, resta il fatto che bcrypt è più sicuro, e quindi non vedo alcun motivo per non usarlo.
Johannes Gorset,

10
@Cypher: bcryptè progettato per essere lento nell'interesse di essere altrettanto lento da decifrare.
Johannes Gorset,

23

Penso che usare md5 o sha256 o qualsiasi hash ottimizzato per la velocità sia perfettamente perfetto e sono molto curioso di sentire qualsiasi rebuttle altri utenti potrebbero avere. Ecco i miei motivi

  1. Se si consente agli utenti di utilizzare le password deboli come Dio, l'amore, la guerra, la pace allora non importa la crittografia sarà ancora permettendo all'utente di digitare la password non l'hash e le password sono spesso utilizzati prima, quindi questo è non andando avere a che fare con la crittografia.

  2. Se non si utilizza SSL o non si dispone di un certificato, gli aggressori che ascoltano il traffico saranno in grado di estrarre la password e qualsiasi tentativo di crittografia con javascript o simili è lato client e facilmente crackabile e superato. Anche in questo caso NON avrà nulla a che fare con la crittografia dei dati sul lato server.

  3. Gli attacchi di forza bruta trarranno vantaggio da password deboli e di nuovo perché permetti all'utente di inserire i dati se non hai la limitazione di accesso di 3 o anche un po 'di più, il problema NON avrà più nulla a che fare con la crittografia dei dati.

  4. Se il tuo database viene compromesso, molto probabilmente tutto è stato compromesso, comprese le tue tecniche di hashing, non importa quanto sia stato criptico. Ancora una volta questo potrebbe essere un attacco XSS dipendente scontento o iniezione sql o qualche altro attacco che non ha nulla a che fare con la crittografia della password.

Credo che dovresti comunque crittografare, ma l'unica cosa che posso vedere è che impedire alle persone che hanno già o in qualche modo ottenuto l'accesso al database di leggere ad alta voce la password. Se è una persona non autorizzata nel database, allora hai grossi problemi di cui preoccuparti, ecco perché Sony è stata presa perché pensavano che una password crittografata proteggesse tutto, compresi i numeri di carta di credito, tutto ciò che fa è proteggere quel campo.

L'unico puro vantaggio che posso vedere per le complesse crittografie delle password in un database è ritardare i dipendenti o altre persone che hanno accesso al database semplicemente leggendo le password. Quindi, se si tratta di un piccolo progetto o qualcosa di cui non mi preoccuperei molto della sicurezza sul lato server, invece mi preoccuperei di più di proteggere qualsiasi cosa un client potrebbe inviare al server come iniezione SQL, attacchi XSS o la pletora di altri modi in cui potrebbe essere compromesso. Se qualcuno non è d'accordo, non vedo l'ora di leggere un lato che una password super crittografata è un must dal lato client.

Il motivo per cui volevo provare a chiarire questo è perché troppo spesso le persone credono che una password crittografata significhi che non devono preoccuparsi che venga compromessa e smettono di preoccuparsi di proteggere il sito Web.


1
Ben dichiarato. La sicurezza informatica deve essere preferita alle tecniche di hashing, non solo salvano i tuoi dati ma mantengono pronta anche la difesa del server.
CᴴᴀZ

14
Questo è davvero male informato. Naturalmente, l'hashing sicuro delle password nel database non migliora la sicurezza a livello di applicazione o di database. Non è un problema per la sicurezza. Vuoi hash sicuro della password utente nel tuo database per 2 motivi; prima il cliente si fida di te con la sua password, che può o non può usare su altri siti, quindi vuoi assicurarti che non sia recuperabile, anche se il tuo db è compromesso, in secondo luogo, vuoi rimuovere la responsabilità in caso di sicurezza violazione. Non conosco nessuna causa legale, ma la perdita di password rende la tua azienda davvero brutta.
James McMahon,

6
Questo è un cattivo consiglio. Se qualcuno ruba il tuo database e ottiene tutte le tue password con hash, anche se hanno compromesso anche altre parti del tuo database, può comunque essere importante impedire loro di decifrare le password e accedere. (Pensa ad un sito web bancario, per esempio.) Gli algoritmi ottimizzati per la velocità consentono agli aggressori di testare molti candidati contro gli hash rubati fino a quando non trovano una corrispondenza. Algoritmi come bcrypt e scrypt rendono lento e costoso testare i candidati contro l'hash, anche se sanno quale algoritmo si utilizza. Quindi offrono una migliore protezione se qualcuno ruba gli hash.
Richard,

6
"Se il tuo database viene compromesso, molto probabilmente tutto è stato compromesso, comprese le tue tecniche di hashing, non importa quanto sia stato criptico." Ecco perché bcrypt è così importante. Con bcrypt, non importa se qualcuno ha gli hash. Con un algoritmo di hashing veloce come SHA1 / MD5, lo fa.
Ceejayoz,

Penso che il punto che manca a qualcuno di voi sia che non importa se la password è sicura al 1000% quando tutti gli altri dati sono in chiaro. Ad esempio, se l'intero database è compromesso, l'hacker ora ha tutti i numeri di carta di credito in chiaro. Sì, molte persone usano la stessa password su siti Web diversi, ma è già stato detto alla nausea di non farlo, quindi non è più un nostro problema. Se il database stesso contiene informazioni riservate e il suo compromesso è un problema, crittografa l'intero database, con la forza che ritieni necessaria.
UncaAlby,

15

Come sottolineato da Johannes Gorset, il post di Thomas Ptacek di Matasano Security spiega perché le semplici funzioni di hashing per scopi generici come MD5, SHA1, SHA256 e SHA512 sono scelte di hashing password scadenti .

Perché? Sono troppo veloci: puoi calcolare almeno 1.000.000 di hash MD5 al secondo per core con un computer moderno, quindi la forza bruta è fattibile contro la maggior parte delle password che le persone usano. E questo è molto meno di un cluster di server cracking basato su GPU!

Salare senza allungare i tasti significa solo che non puoi precompilare la tabella arcobaleno, devi costruirla ad hoc per quel sale specifico. Ma non renderà le cose molto più difficili.

L'utente @Will dice:

Tutti ne parlano come se potessero essere hackerati su Internet. Come già detto, i tentativi di limitazione rendono impossibile decifrare una password su Internet e non hanno nulla a che fare con l'hash.

Non ne hanno bisogno. Apparentemente, nel caso di LinkedIn hanno utilizzato la comune vulnerabilità dell'iniezione SQL per ottenere la tabella DB di accesso e decifrare milioni di password offline.

Quindi torna allo scenario di attacco offline:

La sicurezza entra davvero in gioco quando l'intero database viene compromesso e un hacker può quindi eseguire 100 milioni di tentativi di password al secondo contro l'hash md5. SHA512 è circa 10.000 volte più lento.

No, SHA512 non è 10000 volte più lento di MD5 - richiede solo circa il doppio. Crypt / SHA512 , d'altra parte, è una bestia molto diversa che, come la sua controparte BCrypt, esegue lo stiramento delle chiavi , producendo un hash molto diverso con un sale casuale incorporato e impiegherà tra le 500 e le 999999 volte tanto da calcolare (lo stretching è sintonizzabile).

SHA512 => aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
Crypt/SHA512 => $6$rounds=5000$usesomesillystri$D4IrlXatmP7rx3P3InaxBeoomnAihCKRVQP22JZ6EY47Wc6BkroIuUUBOov1i.S5KPgErtP/EN5mcO.ChWQW21

Quindi la scelta per PHP è Crypt / Blowfish (BCrypt), Crypt / SHA256 o Crypt / SHA512. O almeno Crypt / MD5 (PHK). Vedi www.php.net/manual/en/function.crypt.php


L'hash della password semplice va bene, spetta al firewall mantenere il server sicuro .. e per "firewall" intendo un firewall reattivo che blocca / rallenta la forza bruta (un essere umano può solo digitare QUEL veloce) .. questo il contest è inutile ... Le password sono violate soprattutto perché sono troppo dannatamente semplici o gli sviluppatori di software sono troppo dannatamente pigri per pensare come un cyber criminale.

@argon Per favore, rileggi. L'intero scopo dell'hash delle password è in modo tale che quando il tuo DB di accesso è compromesso (e lo farà ad un certo punto) non perdi immediatamente tutte le password degli utenti, che sono spesso riutilizzate dagli utenti su siti diversi, altrimenti un semplice ritardo dopo l'input farebbe. E il "game over se sono entrati nel tuo server" è un punto controverso, perché non hanno bisogno di entrare nel tuo server. La vulnerabilità più comune che usano gli hacker è stata l'iniezione SQL (vedi il caso Linkedin), quindi hanno potenziato l'hash. Ecco perché hai bisogno di salare e allungare.
LexLythius il

se i requisiti di sicurezza sono davvero così intensi, archiviare password altrove potrebbe essere una buona idea. Esistono molti modi per proteggere i tuoi dati (e il codice sorgente) -per "if / when" ... .. -ma avere le password di hashing fino a "bit gazillion" è sicuro solo come: il creatore di password / sistema guest , la trasmissione dei dati e gli umani che si occupano dell'hardware del server. .. detto questo: NON sto dicendo che l'hashing sia inutile, tuttavia sto dicendo che se la tua soluzione è solo hash più complicati, temo che non funzionerà nel prossimo futuro, per quanto riguarda i computer quantistici.

L'hash ricorsivo aggiunge lavoro / costo a qualsiasi tentativo di hacking. Più iterazioni, più difficile da rompere, quindi potrebbero essere utilizzati anche hash veloci come SHA256. Le iterazioni devono essere casuali e possono essere rese pubbliche. password_hash()mostra il costo nell'hash stesso.
Victor Stoddard,

@VictorStoddard Sì, puoi creare il tuo schema di hashing e fornire un allungamento dei tasti regolabile. Ma perché si vuole fare che invece di utilizzare già esistenti, algoritmi molto più a fondo scrutinate che gli esperti hanno creato e reso disponibile proprio per questo scopo?
LexLythius,

13

Usa SHA256. Non è perfetto, come SHA512sarebbe l'ideale per un hash veloce, ma fuori dalle opzioni, è la scelta definitiva. Come per qualsiasi tecnologia di hashing, assicurati di salare l'hash per una maggiore sicurezza.

Come nota aggiuntiva, FRKT, per favore mostrami dove qualcuno può facilmente rompere un hash SHA256 salato? Sono davvero molto interessato a vedere questo.

Modifica importante:

Andando avanti, si prega di utilizzare bcryptcome hash indurito. Ulteriori informazioni possono essere trovate qui .


Modifica su Salatura:

Utilizzare un numero casuale o un flusso di byte casuale ecc. È possibile utilizzare anche il campo univoco del record nel database come salt, in questo modo il salt è diverso per utente.


1
Ma sono ottimizzati per la velocità, nel senso che abilitano l'hacking a forza bruta.
Arbales,

6
Il fatto rimane, questo è per proteggere una password. Usando un hash con un sale, quindi aggiungi un limite di 3 tentativi sul sito web, rallenti sostanzialmente i tentativi degli hacker (anche i forzanti brutali). Utilizzando qualsiasi crittografia pura, ora hai un altro problema: proteggere la chiave. Se viene trovata la chiave, l'intero database viene compromesso (se non viene aggiunto alcun sale). Hash comunque, non otterrai mai la password originale dal sistema, ed è così che dovrebbe essere.
Kyle Rosendo,

1
Come notato, il problema con le serie MD e SHA è che sono ottimizzati per la velocità. È inevitabile che hash di questa natura diventino sempre più insicuri man mano che il computer si evolve.
Johannes Gorset,

1
Tutto diventa sempre più cattivo / insicuro / ecc. Man mano che l'informatica si evolve. Quando SHA512 ecc. Vengono hackerati, saranno disponibili algoritmi più sicuri. Questa è la natura dell'informatica in ogni caso.
Kyle Rosendo,

1
qual è un buon modo per fare un sale in php? hai un codice di esempio? immagino che non dovrei semplicemente scegliere qualcosa come "giraffa"
Tony Stark,

4

Quello che sembra mancare alla gente è che se l'hacker ha accesso al database probabilmente ha anche accesso al file php che contiene la password e probabilmente può semplicemente modificarlo per inviargli tutte le combinazioni di password nome utente di successo. Se non ha accesso alla directory web, può sempre scegliere semplicemente una password con l'hash e scriverla nel database. In altre parole, l'algoritmo hash non importa tanto quanto la sicurezza del sistema, e limitando i tentativi di accesso anche se non si utilizza SSL, l'attaccante può semplicemente ascoltare la connessione per ottenere le informazioni. A meno che non sia necessario che l'algoritmo richieda molto tempo per il calcolo (per i propri scopi), SHA-256 o SHA-512 con un sale specifico dell'utente dovrebbero essere sufficienti.

Come misura di sicurezza aggiuntiva imposta uno script (bash, batch, python, ecc.) O programma e assegnagli un nome oscuro e fallo controllare e vedi se login.php è cambiato (controlla data / ora) e ti manda una email se ha. Inoltre dovrebbe probabilmente registrare tutti i tentativi di accesso con diritti di amministratore e registrare tutti i tentativi falliti di accedere al database e ricevere i registri via e-mail.


"Quello che sembra mancare alla gente è che se l'hacker ha accesso al database probabilmente ha anche accesso al file php che ha la password ..." Questo non è vero. Una delle vulnerabilità più comuni è l'iniezione di SQL, che darebbe capacità di lettura / scrittura al database ma zero accesso al codice PHP.
Ceejayoz,

Se hai accesso al codice, puoi modificare e memorizzare tutta la password che l'utente sta inviando in un testo semplice. Quindi no, se il codice è compromesso, GAME OVER.
Magallanes,

3

Tutti ne parlano come se potessero essere hackerati su Internet. Come già detto, i tentativi di limitazione rendono impossibile decifrare una password su Internet e non hanno nulla a che fare con l'hash.

Il sale è un must, ma la complessità o i sali multipli non contano nemmeno. Qualsiasi sale da solo impedisce all'aggressore di usare un tavolo arcobaleno premade. Un unico sale per utente impedisce all'autore dell'attacco di creare una nuova tabella arcobaleno da utilizzare contro l'intera base utenti.

La sicurezza entra davvero in gioco quando l'intero database viene compromesso e un hacker può quindi eseguire 100 milioni di tentativi di password al secondo contro l'hash md5. SHA512 è circa 10.000 volte più lento. Una password complessa con la potenza di oggi potrebbe richiedere ancora 100 anni per la forza bruta con md5 e richiederebbe 10.000 volte di più con SHA512. I sali non fermano affatto una forza bruta poiché devono sempre essere conosciuti, che se l'attaccante ha scaricato il tuo database, probabilmente si trovava comunque nel tuo sistema.


1

MD5 è un problema a causa di problemi di collisione: due password diverse potrebbero generare lo stesso md-5.

Sha-1 sarebbe molto sicuro per questo. Il motivo per cui memorizzi la versione sha-1 salata della password è che il swerver non tiene in archivio l'apassword dell'utente, che potrebbe utilizzare con i server di altre persone. Altrimenti, che differenza fa?

Se l'hacker ruba l'intero database non crittografato in qualche modo, l'unica cosa che fa una password salata con hash è impedirgli di impersonare l'utente per accessi futuri - l'hacker ha già i dati.

A che serve l'attaccante avere il valore con hash, se ciò che l'utente immette è una semplice password?

E anche se un hacker con tecnologia futura potesse generare un milione di sha-1 chiavi al secondo per un attacco di forza bruta, il tuo server gestirà un milione di accessi al secondo affinché l'hacker possa testare le sue chiavi? Questo è se stai lasciando che l'hacker tenti di accedere con sha-1 salato invece di una password come un normale accesso.

La scommessa migliore è limitare i tentativi di accesso errati a un numero ragionevole, ad esempio 25, e quindi far scadere l'utente per un minuto o due. E se i tentativi di accesso cumulativi non validi raggiungono 250 entro 24 ore, chiudi l'accesso all'account e invia un'email al proprietario.


Anche se sto usando una crittografia più debole, praticamente nessun sistema può sostenere un attacco brutale per oltre 1 milione di tentativi al secondo.
Magallanes,

1
Tre accessi non riusciti e sei bloccato. Periodo, fine della storia. Anche le password super stupide come "1234" sono sicure, se l'hacker prova prima a provare "password", "pa $$ word" e "passw0rd" (blocca!). Il modo in cui l'utente riacquista l'accesso ora diventa il punto critico della tua sicurezza e ciò che fai dipende dalle dimensioni della tua base di utenti. 200 utenti? Fagli telefonare per chiedere aiuto.
UncaAlby,

Questa risposta non ha senso per qualcun altro, o sono solo io?
Wildcard il


1

Usa argon2i . La funzione di hashing della password argon2 ha vinto la competizione di hash della password.

Altre scelte ragionevoli, se l'utilizzo di argon2 non è disponibile, sono scrypt , bcrypt e PBKDF2 . Wikipedia ha pagine per queste funzioni:

MD5, SHA1 e SHA256 sono digest dei messaggi, non funzioni di hashing della password. Non sono adatti a questo scopo.

Il passaggio da MD5 a SHA1 o SHA512 non migliorerà così tanto la sicurezza della costruzione. Il calcolo di un hash SHA256 o SHA512 è molto veloce. Un utente malintenzionato con hardware comune potrebbe ancora provare decine di milioni (con una sola CPU) o addirittura miliardi (con una singola GPU) di hash al secondo. Le buone funzioni di hashing delle password includono un fattore di lavoro per rallentare gli attacchi del dizionario.

Ecco un suggerimento per i programmatori PHP: leggi le FAQ di PHP quindi usa password_hash () .


0

Supponiamo il punto successivo: gli hacker rubano il nostro database, inclusi gli utenti e la password (crittografata). E gli hacker hanno creato un account falso con una password che conoscono.

MD5 è debole perché è breve e popolare e praticamente ogni generazione di hash senza password è debole di un attacco del dizionario. Ma..

Quindi, supponiamo che stiamo ancora usando MD5 con un SALT. Gli hacker non conoscono il SALT ma conoscono la password di un utente specifico. Quindi possono testare: ????? 12345 dove 12345 è la password conosciuta e ????? è il sale. Gli hacker prima o poi possono indovinare il SALT.

Tuttavia, se abbiamo usato un MD5 + SALT e abbiamo applicato MD5, allora non c'è modo di recuperare le informazioni. Tuttavia, ripeto, MD5 è ancora breve.

Ad esempio, supponiamo che la mia password sia: 12345. Il SALE è BILLCLINTON

md5: 827ccb0eea8a706c4c34a16891f84e7b

md5 con l'hash: 56adb0f19ac0fb50194c312d49b15378

mD5 con l'hash over md5: 28a03c0bc950decdd9ee362907d1798a Ho provato a usare quel servizio online e non ho trovato nessuno in grado di risolverlo. Ed è solo MD5! (potrebbe essere come oggi sarà crackabile perché ho generato il md5 online)

Se vuoi esagerare, SHA256 è più che sufficiente se applicato con un sale e due volte.

tldr MD5 (HASH + MD5 (password)) = ok ma breve, SHA256 è più che sufficiente.


Il problema con l'utilizzo di MD5 con un salt è che i computer possono creare un attacco di forza bruta su una password con velocità super veloci. shylor.com/2015/09/14/php-5-5-secure-password-hashing
Shylor

0

Una crittografia md5 è una delle peggiori, perché devi girare il codice ed è già decrittografato. Ti consiglierei lo SHA256. Sto programmando un po 'di più e ho avuto una buona esperienza. Di seguito sarebbe anche una crittografia.

password_hash() example using Argon2i

<?php
echo 'Argon2i hash: ' . password_hash('rasmuslerdorf', PASSWORD_ARGON2I);
?>
The above example will output something similar to:

Argon2i hash: $argon2i$v=19$m=1024,t=2,p=2$YzJBSzV4TUhkMzc3d3laeg$zqU/1IN0/AogfP4cmSJI1vc8lpXRW9/S0sYY2i2jHT0
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.