Schema di memorizzazione delle password decisamente più sicuro?

3

L'ho già chiesto su StackOverflow ma mi è stato suggerito che sarebbe stato un posto più adatto e non ho trovato alcun modo per "spostare" la domanda, quindi devo copiarla.

Credi, lo so, ci sono centinaia di domande su questo problema. Li ho letti per trovare il modo più sicuro di memorizzare una password, ma ogni risposta fornita mi dà la sensazione pruriginosa che possiamo ancora fare molto meglio. E sto pensando di usarlo in PHP, ma penso che si applichi a qualsiasi linguaggio di programmazione.

Non sono un esperto di sicurezza ma non è solo un metodo non abbastanza sicuro?

ENCRYPT

Se ho capito bene, la password crittografata (con PHP) può essere decrittografata in chiaro se si conosce la stringa utilizzata. La maggior parte degli account di hosting che ho visto compromesso prima ottengono l'accesso ai file e quindi cercano la password del DB memorizzata in config.php o giù di lì.

Anche se uso una stringa grande e complicata per crittografare la password, se l'intruso va su create_account.php (o ovunque venga creato l'utente), troverà la stringa lì e sarà in grado di decodificare l'intera password colonna in pochi minuti (giusto?)

hashing

La cosa buona dell'hashing è che la password non può essere restituita in testo semplice, il che è ottimo ma ... Molti metodi di hashing hanno degli exploit e ho letto alcuni articoli che ottengono i possibili valori per un hashing (un stringa hash può significare più di una stringa di testo semplice). Ho letto un articolo che diceva che alcune persone erano in grado di recuperare la password dall'hash utilizzando Amazon EC2 in pochi secondi per password deboli e ore per quelle forti.

Ho persino visto le directory degli indici di hashing dove hacker e j * rks casuali memorizzano enormi quantità di valori di stringa hash > quindi se inserisci l'hash che hai ottenuto, puoi ottenere la password in un solo secondo. Questa è ancora una specie di attacco di dizionario ma piuttosto efficace.

Per un hash comune come MD5 ho persino visto un articolo in cui un hacker ha facilmente rilevato che Google indicizza in qualche modo gli hash MD5 a causa di quanto viene usato (come nei nomi dei file, gravatar.com e API simili, ecc.) dizionario HUUUGE indicizzato di hash che richiede solo un secondo per associare ai valori.

MD5 e SHA1 una volta erano considerati sicuri ma poi sono apparsi degli exploit. Cosa succede se il metodo fidato usato ora (ho letto blowfish è il migliore, è corretto?) Ottiene qualche exploit in futuro?

E infine, so che è ridicolo, ma mi sento a disagio con la possibilità che 2 password abbiano lo stesso risultato di hash. Lo so, le possibilità di qualcuno che indovina l'altro valore che ha lo stesso hash è bassa, ma HEY, siamo nel 2012 !, non dovevamo avere macchine volanti e computer che potrebbero rendere il film Avatar in un'ora già ? : P Ci dovrebbe essere qualcosa di meglio già ...

SALE

Anche se utilizzo un salt per rendere più difficile il recupero della password, se l'hacker vede la stringa salata fissa (o dove è stato memorizzato il sale casuale) non renderebbe molto più complicata la forza bruta con un attacco computazionale del cloud , vero?

NON CI SONO QUALCOSA MEGLIO?

Come ho detto, sono ben lungi dall'essere un esperto di sicurezza, ma non c'è nessuna opzione là fuori? Ho letto molte domande a riguardo qui in Stack Overflow e risultato Google (che la maggior parte sono risposte di overflow dello stack: D) e dicono praticamente sempre la stessa cosa.

Se l'hashing e la crittografia sono le uniche opzioni, è un modo per migliorarlo? C'è un modo per nascondere la password di crittografia nel caso in cui il file che crea gli utenti sia accessibile?

In tutte quelle risposte non ho mai visto qualcuno suggerire di combinare metodi come:

sha1 (cripta [blowfish.salt], sale) Questa è una cattiva idea per qualche motivo? (Posso solo pensare di consumare troppo processore in un sito con migliaia di utenti che si registrano e si collegano, ma posso gestirlo nei siti che sto pianificando di usarlo)

Non sto chiedendo "per favore codificalo per me", voglio sapere come renderlo "il più possibile impossibile" (il più difficile: P) per ottenere le password nel caso in cui il DB e il codice sorgente siano mani sbagliate

Forse ho frainteso il modo in cui funzionano questi metodi e forse c'è qualcosa come una funzione PHP per rendere una stringa non decifrabile anche con la password, o forse mi sono perso qualcosa. Trovo ancora strano che nessuno abbia suggerito una combinazione di metodi.

Grazie in anticipo e grazie ancora se stai ancora leggendo i pensieri della mia mente preoccupata

    
posta Juan 22.02.2012 - 08:51
fonte

11 risposte

7

È possibile delegare l'autenticazione a un server diverso all'interno della rete, a cui il server principale comunica tramite un servizio web o qualsiasi protocollo desiderato. In questo modo un hacker può accedere al tuo server e ai tuoi file primari e non ottenere ancora nulla.

Il server di autenticazione può essere bloccato molto più stretto, riducendo al minimo l'area di superficie per l'attacco - per non parlare del fatto che l'attacco dovrebbe avvenire via il tuo server primario.

    
risposta data 22.02.2012 - 08:36
fonte
7

Non crittografare le password - (unidirezionali) su di esse.

Non dovresti aver bisogno o vuoi decrittografare le password. Se lo fai, non sei così preoccupato per la sicurezza.

La sicurezza è sempre un compromesso con le prestazioni.

Gli algoritmi di hash standard (md5, sha1) sono sicuri a meno che il sale non sia noto all'attaccante.

L'uso di un algoritmo di hashing lento rende le password sicure anche se un utente malintenzionato ha accesso al codice e all'hash memorizzato.

La funzione crypt è probabilmente quello che vuoi in php. L'utilizzo di un numero elevato di cicli di crittografia renderà più lento il calcolo dell'hash di un determinato input; ciò lo renderà impossibile alla forza bruta ma renderà anche lento per te / la tua applicazione verificare che la password immessa dall'utente sia la stessa dell'hash che hai archiviato - questo è il compromesso.

Raddoppiare le tecniche non farà nulla per aumentare la sicurezza - il parametro di crittografia round in the sale significa che sta alimentando l'output di hashing della stringa di input nell'algoritmo di hashing che molte volte - Stai proponendo un bespoke + 1, basta aggiungerne uno al numero di round che si desidera eseguire. Inoltre, per l'esempio dato sha1(crypt[blowfish.salt],salt) questo ti impedirebbe di essere in grado di confrontare correttamente l'hash con l'input dell'utente - da Il primo esempio :

You should pass the entire results of crypt() as the salt for comparing a password

Senza l'output di crypt, non puoi confrontare l'input dell'utente con l'hash già generato.

    
risposta data 22.02.2012 - 12:15
fonte
7

Schema di archiviazione delle password più sicuro? Un strong hash lento (come bcrypt) con diversi byte random salt che impedisce di attaccare le password in parallelo con una tabella arcobaleno. La crittografia delle password deve essere utilizzata solo se assolutamente necessario: ad esempio, sei registrando una password per un sistema esterno che non controllare che sia troppo stupido per utilizzare un protocollo sano di concessione dell'accesso di terze parti (come openauth), quindi è necessario registrare la password degli utenti su quel sistema.

And lastly, I know this is ridiculous but I'm uncomfortable with the possibility of 2 passwords having the same hash result. I know, the possibilities of somebody guessing the other value that has the same hash is veeeeeery low, but HEY, we're in 2012!, weren't we supposed to have flying cars and computers that could render Avatar movie in an hour already? :P There should be something better already...

Sì, il tuo disagio è ridicolo. Se si usa dire SHA256 (256 bit) o bcrypt (184 bit), la possibilità di ottenere due password casuali sullo stesso hash è straordinariamente improbabile (circa 10 66 volte meno probabile di vincere il jackpot powerball ). Per SHA256 tutte le password dovrebbero essere uniche fino a quando non si hanno circa 2 password 256/2 ~ 10 38 memorizzate nella tabella e quindi circa la metà delle volte che saranno un set di password duplicate. Per far sì che una determinata password abbia probabilmente una seconda stringa che esegue il mapping allo stesso hash, è necessario circa 2 256 ~ 10 77 . (Tutti questi presuppongono che le funzioni di hash abbiano una buona uniformità).

Mettiamo questi grandi numeri in prospettiva. La massa della Terra è di circa 6x10 ^ 24 kg. Pertanto, se si utilizzano in media 50 byte per memorizzare ciascuna password in una tabella arcobaleno, prima che sia probabile un duplicato con SHA256 occorrono circa 10 ^ 30 gigabyte di dati. Se lo metti in termini di tutti i dischi rigidi da 3 TB ognuno dei quali pesa circa mezzo kg, i tuoi dischi rigidi peserebbero circa 1000 volte di più della Terra. O come confronto per avere la probabilità che la maggior parte degli hash abbia più stringhe, confrontare il 10 77 numero di hash SHA256 necessario ad essere un miliardo di volte inferiore al numero di atomi nella Via Lattea (circa 10 < sup> 68 ).

    
risposta data 22.02.2012 - 20:24
fonte
6

Giusto - prima di tutto, ci sono un sacco di domande qui, quindi mentre avrò un rapido andare, probabilmente dovresti prima leggere le domande collegate a lato e quelle con e tag. Molte delle tue domande hanno ricevuto risposta. In realtà, sono tutti tranne la tua domanda specifica su dove memorizzare la chiave di crittografia.

Un breve riepilogo:

  1. PHP - generalmente considerato piuttosto insicuro. Può essere fissato a vari livelli, ma la struttura e il rigonfiamento funzionale che spesso ne deriva implica che se la sicurezza è il tuo obiettivo principale, i rischi dovrebbero essere apprezzati molto attentamente.
  2. Non memorizzare le chiavi di crittografia con dati pubblici. In un ambiente completamente ospitato questo può essere difficile da gestire, ma è un grosso rischio.
  3. Sì, le tabelle arcobaleno ti consentono di recuperare le password dagli hash in pochi secondi se non usi salting - gli hash dovrebbero usare i sali e un algoritmo lento . Questo può essere fatto in modo molto sicuro (ad esempio, la forzatura bruta impiega un tempo incredibilmente lungo - più lungo della vita dell'universo, per esempio)
risposta data 22.02.2012 - 10:09
fonte
3

Dovresti eseguire l'hashing delle tue password (con HMAC + bcrypt), non crittografarle. Ecco alcune regole generali che seguo:

  1. Utilizza un algoritmo che offre limiti di tempo sufficienti (ad es., bcrypt). Questo perché, bcrypt ti permette di personalizzare il lavoro richiesto per calcolare ogni hash che aiuta a ridurre il numero di tentativi di forza bruta che un attaccante può preformare in un dato intervallo di tempo.

  2. Utilizza per i sali utente. Usando i sali per utente, puoi essere certo che nessun utente con la stessa password avrà lo stesso hash. Riduce anche il rischio associato ai tavoli arcobaleno.

  3. Utilizza un sistema salt saltato, che non è archiviato nel database. Questo fornisce un ulteriore livello di sicurezza in caso di compromissione completa del DB in cui sia l'hash delle password che i sali sono compromessi . Usando un altro sale che viene memorizzato solo nella memoria, un utente malintenzionato non sarebbe in grado di forzare facilmente la password di ogni utente.

risposta data 22.02.2012 - 18:14
fonte
3

Sì, ci sono "centinaia" di domande su questo problema. Questo mi ha costretto scrivere un articolo su di esso che spero risponda una volta per tutte:

link

Essenzialmente, l'archiviazione sicura delle password implica:

  • L'algoritmo giusto - usa bcrypt o PBKDF2 , entrambi algoritmi lenti che hash password con il loro "sale". La crittografia non è l'ideale perché l'esatto la password può essere recuperata se la chiave è nota, il che non è necessariamente il caso dell'hashing. MD5, SHA-1, ecc. Da soli non sono l'ideale, perché non sono abbastanza "lenti".

  • La giusta politica per le password - come forzare gli utenti a usare password lunghe, e incoraggiando password complesse.

Aggiungi commenti per aiutarmi a migliorare l'articolo.

    
risposta data 22.02.2012 - 10:22
fonte
1

Prima di tutto, devi sempre seguire il principio dei privilegi minimi . Anche se non direttamente applicabile in questo caso, dovrebbe significare che, a meno che sicuramente non abbia bisogno della password originale (ad esempio autenticazione remota), non utilizzare uno schema che permetta di recuperare la password originale.

Quindi la crittografia viene presa in considerazione solo se sicuramente è necessario ottenere la password originale. Altrimenti, memorizza solo un hash della password.

Come per lo schema di hashing, dovresti usare uno che è stato specificamente progettato per l'hashing / memorizzazione di password (per esempio crypt ). Oltre alle funzioni di hash crittografiche generiche come quelle delle famiglie MD o SHA, molte di esse aggiungono un fattore di costo temporale aggiuntivo e regolabile che rende gli attacchi a forza bruta meno efficienti / più difficili.

Parlando di attacchi a forza bruta, usa un salt unico per ogni password con hash. Alcuni schemi di password come crypt già applicano la salatura automatica . Usalo e non provare a inventare il tuo sistema.

    
risposta data 22.02.2012 - 12:04
fonte
1

Dovresti usare le password hash archiviate nel database con un salt. Non proverei a scrivere la mia libreria di hashing delle password. Uno molto popolare che è utilizzato in molti progetti PHP (incluso il mio) è phpass da link - può creare hash salati usando bcrypt , DES o MD5.

Per aiutare gli utenti a creare password più sicure, puoi richiedere loro di creare password di una certa lunghezza o complessità.

    
risposta data 22.02.2012 - 16:01
fonte
0

Posso darti rapidamente la funzione che uso per le password hash (la chiave è, ovviamente, modificata qui):

$siteLongKey = '5efd8123878793f88bf1362905ae209794a8602f92969a67862b925fd6e50b04dfd31ae74002cb449824fcaa90e2efd096e8653a3f52e2b048e24b289c705129';

    function hashPassword($password, $nonce = '') {
      global $siteLongKey;    
      return hash_hmac('sha512', $password . $nonce, $siteLongKey);
    }

Questo è abbastanza buono, $ siteLongKey è la tua chiave globale e $ nonce è il sale che puoi aggiungere. Potrebbe essere l'indirizzo email o la data di creazione dell'account o qualsiasi informazione statica relativa all'account. In questo caso, ogni utente ha un sale diverso. Questo è l'hashing a senso unico e (in teoria) non esiste il recupero della password ma solo la reimpostazione della password.

    
risposta data 22.02.2012 - 08:39
fonte
-2

L'opzione migliore per archiviare le password in db è la crittografia unidirezionale che utilizza l'algoritmo Digest di messaggistica che produce un valore hash a 128 bit e non può essere decodificato. Quindi il recupero della password non è possibile. Per autenticare qualsiasi utente, creiamo sempre l'hash della password fornita e confrontiamo entrambi i valori hash.

Se si utilizzano algoritmi personalizzati per crittografare e decodificare la password, utilizzare ionCube per utilizzare i codici binari dei propri algoritmi. quindi, anche se l'hacker dovesse entrare nel codice, sarà inutile. puoi controllare qui link questo è un altro modo migliore per andare al sicuro ..

    
risposta data 22.02.2012 - 08:39
fonte
-2

Il miglior algoritmo attualmente disponibile è bcrypt. Tuttavia, a novembre è stato inventato un algoritmo migliore e una domanda di brevetto viene lentamente preparata per questo. L'algoritmo può essere disponibile in non meno di 18 mesi (periodo di non divulgazione obbligatoria dell'OMPI). L'utilizzo gratuito sarà disponibile solo con distribuzioni Linux non commerciali.

    
risposta data 22.02.2012 - 17:17
fonte

Leggi altre domande sui tag