Questo approccio consente una gestione delle password sicura e in grado di perdonare le lettere?

3

Anni fa ho espresso un'opinione che rendere la gestione delle password indulgente, accettando forse un singolo carattere sbagliato, costerebbe un'entropia, ma non lascerebbe aperta la porta della stalla; un altro carattere entropico o due dovrebbero (ho pensato) essere sufficienti a compensare la perdita di entropia accettando i quasi-incidenti.

Ho anche detto che non ho visto alcun modo che non avrebbe sostenuto problemi di implementazione killer; una sfocata corrispondenza con una password in chiaro memorizzata potrebbe urlare " STORED PLAINTEXT PASSWORD " ai professionisti della sicurezza e affondare come una roccia.

Tuttavia, cosa accadrebbe se fossero memorizzate più password codificate con trapdoor: la "vera" password e tutte le varianti che soddisfano uno standard di tolleranza agli errori inteso a prevedere gli errori di battitura più "near-miss". Tale criterio potrebbe essere strettamente vincolato ai requisiti near-miss e tollerare solo un near-miss piuttosto che due, ma mentre comporterebbe uno schema diverso, sarebbe possibile avere più password (l'originale come varianti dattiloscritte e leggermente indulgenti) senza l'innervosissima insicurezza di memorizzare password in chiaro.

Quali sono le responsabilità di sicurezza di questo approccio al di sopra della perdita di entropia avendo forse un paio di ordini di grandezza più stringhe che sarebbero accettate? Se un utente malintenzionato ha un centinaio di password crittografate che sono tutte varianti di errore di battitura su una singola password, è possibile scomporre una password potenzialmente più semplice di cento password crittografate completamente non collegate?

Dal punto di vista dell'esperienza utente, immagino ci siano alcuni tipi di UX che verrebbero ignorati, se devi digitare una password piuttosto che ad es. Facebook OAuth, che mostra la tolleranza agli errori di battitura più comuni nell'inserimento delle password.

    
posta JonathanHayward 01.04.2017 - 17:08
fonte

3 risposte

1

Penso che stai cercando gli hash di quel cluster quando l'input è simile: en.m.wikipedia.org/wiki/Locality-sensitive_hashing

    
risposta data 17.09.2017 - 22:01
fonte
1

Un metodo che potrebbe essere utilizzato sarebbe quello di generare "errori di battitura accettabili" al momento della registrazione della password iniziale, quindi di memorizzare gli hash di tutti questi. Ci sono alcuni problemi con questo: si aumenta il tempo richiesto per una modifica della password e per la verifica della password, soprattutto se si utilizza un metodo di hashing della password lenta, come di solito raccomandato, e si aumentano i requisiti di archiviazione di un importo potenzialmente variabile. / p>

Supponiamo che la password utilizzata sia "Password1!" e che "errori di battitura accettabili" siano il caso di singole lettere (o la presenza di caratteri appropriati dalla pressione di Maiusc e un numero), lo scambio di caratteri adiacenti e la mancanza di un singola istanza di un carattere duplicato (questi non sono gli unici errori di battitura possibili, ma dai miei refusi, sono piuttosto facili da fare!).

Ciò significa che tutti i seguenti sono accettabili:

Password1!
aPssword1!
Psasword1!
Password1! [transposing "s" and "s"]
Paswsord1!
Passowrd1!
Passwrod1!
Passwodr1!
Passwor1d!
Password!1
password1!
PAssword1!
PaSsword1!
PasSword1!
PassWord1!
PasswOrd1!
PasswoRd1!
PassworD1!
Password!!
Password11
Pasword1!

Dato qualsiasi algoritmo di password ragionevole (o MD5), questi avranno tutti hash non collegati:

2b4ae288a819f2bcf8e290332c838148
c435f7c0de60f0f69bce9f9a671e748a
8aed93fca5d9b2416c51fee36b03bc6b
9fbad358027d70c0db81fc23ab483c3c
dbf220c136f6b1f27c30997090da4697
c36fc47e48c2a52e450cd06f60bbd3bf

Per verificare una password in questo caso, si hash l'input e si controllano tutti i valori possibili. Puoi anche salare l'input a livello di account e devi solo calcolare un hash. C'è un difetto però.

Conoscere tutti questi hash in realtà non aiuta direttamente un utente malintenzionato, ma può applicare le stesse regole che hai fatto a qualsiasi elenco di password che hanno, e se uno degli hash corrisponde, ottengono l'accesso all'account - questo si applica se usi anche un sale specifico per l'account. Il compromesso per la velocità di accesso li aiuta anche.

Fortunatamente, è abbastanza facile difendersi da questo, con un sale specifico per l'hash. Se usi la maggior parte delle implementazioni di bcrypt, ottieni questo gratuitamente:

Password1!:$2a$04$GgLXwKnxLmnLV/UUtbYahuT9L8R.8/SoKAnRKZUyCuEEgfrX5ITLm
password1!:$2a$04$5Ol8psikd7h0Gt/ZWtQAve0PdA/LO4oub/0JMGC5AA/Rsup/3SBbG

Ora devono provare tutte le modifiche su ogni hash memorizzato. A seconda di come memorizzi le tue password, potrebbero essere in grado di ottimizzare le varianti che tentano contro ogni hash, ma poiché non sanno se la password corretta è "Password1!" o "pAssword1!", c'è il rischio di perdere le cose se lo fanno. Tuttavia, quando qualcuno vuole accedere, devi fare lo stesso.

Questo è il trade-off - se usi un metodo di hashing che richiede 100ms per calcolare, e devi calcolare 1 valore, ci vorranno 100ms per controllare. Se è necessario controllare 10 versioni, ci vorranno 1s di tempo di elaborazione. Se esegui i controlli uno per uno, si ottiene un problema di temporizzazione: risposte rapide indicano che la password originale è stata trovata, quelle più lente significano che ha un refuso. Se li fai in parallelo, hai aumentato i requisiti di elaborazione per il tuo sistema.

Usando solo l'elenco sopra di "errori accettabili", ottieni un numero variabile di potenziali password. Per "Password1!", Significa che stai memorizzando 21 hash, uno dei quali è un duplicato della password originale. Se si richiede un output di tempo costante durante l'accesso al sistema (questa è una buona cosa), è necessario essere in grado di calcolare tutti questi hash in un dato momento, o di ritardare ogni accesso al tempo necessario per calcolare tutte le hash per la password più lunga che supporti. Se non lo fai, hai creato un oracolo per la lunghezza della password.

Esistono metodi di hashing che consentono a input simili di provocare hash simili, ma questi non tendono ad avere proprietà desiderabili per le password di hashing. Sono generalmente ottimizzati per trovare parti simili di grandi strutture di dati, quindi sono ad alta velocità, il che significa che un gran numero di potenziali password può essere provato rapidamente. Essi, per definizione, non hanno un effetto valanghe, il che significa che un potenziale attacco potrebbe provare password comuni, quindi scegliere l'hash "più vicino" a quelli trovati per ulteriori mutazioni. Se un hash di uscita da una mutazione è "più vicino" a quelli memorizzati, anche l'input è più vicino. Con un hash crittografico, anche veloce, la modifica di un singolo carattere nell'input dovrebbe cambiare la maggior parte dell'output. Non c'è un concetto di "più vicino" in termini di output, quindi un attaccante non può fare meglio dei cambiamenti casuali, sperando di ottenere una corrispondenza.

Se si evita completamente il problema di hashing e si scende lungo la rotta HSM, potrebbe essere possibile avere un HSM che memorizza le password in testo non crittografato in modo irrecuperabile e che potrebbe produrre risposte di "originale", "errore di battitura" e "no" usando metodi di confronto classici. Questo potrebbe essere accettabile se hai permesso ad alcune azioni di accedere agli utenti, ma poi hai richiesto la password corretta per le operazioni ad alto rischio (ad esempio cambiando la password), ma non è probabile che sia economicamente conveniente per la maggior parte dei provider.

È certamente possibile, ma ci sono molti potenziali problemi nel farlo e non è chiaro se i vantaggi di UX giustifichino lo sforzo. Probabilmente sarebbe molto più facile incoraggiare l'uso delle applicazioni di gestione password, poiché eviteranno il rischio di errori di battitura in molti casi!

    
risposta data 16.08.2017 - 17:26
fonte
1

La matematica per calcolare la risposta alla tua domanda è semplice, ma dipende da come perdonare che intendi essere.

Ad esempio, supponiamo che tu permetta che 1 carattere sia errato. Se nella password sono consentiti 80 caratteri diversi e la password è lunga 10 caratteri, anziché 1 hash della password, è necessario memorizzare 1 + 79 * 10 = 791 hash totali. (O calcolarli tutti al volo se non li memorizzi). Poiché gli algoritmi di hashing buoni sono "lenti", è sufficiente verificare se una password è corretta potrebbe diventare notevolmente più lenta.

Forse potresti voler limitare l'errore a solo 8 tasti vicino a ciascun personaggio. Questo certamente riduce il numero di hash totali da controllare (a 81), ma per quanto riguarda le persone che usano un layout di tastiera diverso?

Qualunque algoritmo tu usi, una volta calcolato il numero di hash che dovresti testare, dividi 1 per quel numero per determinare quanto sia meno sicuro. Nel primo esempio, è circa 800 volte più debole, che equivale a ridurre la password a caratteri 8.9 (ish) invece di 10.

    
risposta data 15.09.2017 - 22:47
fonte

Leggi altre domande sui tag