Perché le password devono essere confrontate mediante un array di byte?

4

Una best practice in un processo di accesso di un'applicazione Web è di confrontare le password con hash come array di byte. Qual è la vera ragione di questa best practice? Riguarda l'integrità?

Cert Secure Coding parla dell'uso di array di byte perché sono più facili da rilasciare.

    
posta hmrojas.p 31.10.2017 - 19:17
fonte

2 risposte

16

Ci sono un paio di problemi in gioco qui. Il primo, a cui si fa riferimento sia nella Esempio di Cert Secure Coding a cui sei collegato e la risposta StackOverflow del commento di Daniel Grover non ha nulla di specifico fare con il confronto dell'hash di una password inviata dall'utente con un hash precedentemente memorizzato, ma con la memorizzazione della password di input stessa. Il problema che descrivono è quello dell'immutabilità delle stringhe in piattaforme come Java e .NET, il che significa che se la password del testo in chiaro è mai memorizzata come stringa, non può essere rimossa dall'applicazione, ma solo dal garbage collector, quindi il dump della memoria che si verifica prima che ciò accada può portare all'esposizione di una password in chiaro.

Questo, tuttavia, non è davvero un problema quando si confrontano gli hash delle password. Le ragioni per utilizzare gli array di byte anziché le stringhe hanno meno implicazioni sulla sicurezza, ma è comunque una buona idea. Primo, perché l'input e l'output di una funzione di hash è generalmente sotto forma di byte. Se inserisci dei byte e ottieni i byte, la conversione in una stringa da confrontare ha poco senso. Inoltre, si elimina un'intera classe di bug (che potrebbero includere vulnerabilità di sicurezza) causata da una codifica stringa errata. Ad esempio, due array di byte che rappresentano due password completamente diverse potrebbero erroneamente riportare come identici se convertiti in modo errato in ASCII prima del confronto, perché in molti casi, i byte al di fuori delle basi ASCII di 128 caratteri saranno convertiti nello stesso valore di carattere ASCII (3F), aprendo il potenziale per le collisioni tra stringhe anche quando non lo erano gli array di byte originali. Se lasci da solo i byte, elimini completamente questa potenziale vulnerabilità.

Quindi, pensando a loro e lavorando con loro come sono, un output hash di byte piuttosto che stringhe porta a un codice più semplice, più corretto e meno codice soggetto a errori. Per sicurezza, questa è una buona cosa.

    
risposta data 31.10.2017 - 20:39
fonte
8

Stai confondendo due problemi leggermente ortogonali qui con la dicitura "confronta le password hash"

Memorizzazione della password (prima dell'hashing)

Come dice Jon Skeet su SO:

Strings are immutable (in Java and many other GC languages). That means once you've created the String, if another process can dump memory, there's no way (aside from reflection) you can get rid of the data before garbage collection kicks in.

Se si sta gestendo la password di un utente, si vuole evitare questo rischio, quindi, si utilizza un tipo di dati che è possibile sovrascrivere immediatamente dopo averlo utilizzato: una serie di byte si adatta perfettamente alla fattura. Una volta applicato l'algoritmo di hash della password, puoi riempire l'array (o utilizzare dati casuali o qualsiasi altra cosa).

Confronto degli hash (ad es. dopo l'hashing, prima di accedere)

Le funzioni hash producono byte. È come sono definiti e in genere come funzionano nella maggior parte dei linguaggi di programmazione, quindi ha più senso semplicemente confrontare i due bytestrings così come sono, senza prima eseguirli attraverso qualsiasi convertitore.

Tuttavia, se l'hash della password è codificato in base64 nel database, non vi è alcuna perdita di sicurezza dal prendere l'hash della password calcolata e codificarlo in base64 e quindi confrontare le stringhe. L'hash è già nel tuo database - se un utente malintenzionato ha accesso al tuo sistema sufficiente a scaricare la memoria del processo, non dovrebbe essere troppo lungo per recuperare l'hash della password dal tuo database - non importa se lo pescano da lì o da una copia immutabile conservata fino a quando il tuo GC è in esecuzione.

Riepilogo

Quindi, per semplificare le cose:

  1. Elabora le password utente come array di byte, non utilizzando tipi di stringhe.
  2. Process hash anche come stringhe di byte, poiché non vi è alcun vantaggio nel convertirli solo per il confronto.
  3. Utilizza uno schema di hashing della password sicura. Argon2 se disponibile è attualmente raccomandato, altrimenti segui il consiglio qui: link
risposta data 31.10.2017 - 20:37
fonte

Leggi altre domande sui tag