Nesting bcrypt + PHPass per migliorare la sicurezza dell'archiviazione delle password nei software legacy?

3

Ho ricevuto il compito di migliorare la sicurezza dell'archiviazione delle password di un sito che attualmente utilizza PHPass Openwall . Tutti gli hash verranno convertiti contemporaneamente, i. e. non vogliamo aspettare che l'utente effettui il login per re-hash la propria password.

Per raggiungere questo obiettivo ho pensato che potremmo utilizzare bcrypt sugli hash PHPass esistenti , in questo modo: bcrypt(phpass(password))

Ma abbiamo bisogno di un passaggio intermedio importante: proprio come bcrypt, PHPass ha il proprio sale incorporato nell'hash, quindi dobbiamo "portare" quel sale in bcrypt se vogliamo che l'operazione sia ripetibile durante la verifica degli hash.

Fortunatamente, la dimensione sale di PHPass è più piccola (6 byte) di bcrypt (16 byte), quindi possiamo "condividere" i primi 6 byte del sale e aggiungere 10 byte casuali aggiuntivi per bcrypt.

Immagina qualcosa di simile in pseudo-PHP:

$password = 'somestring123';

$hash = phpass($password)

// $hash is now '$H$9Uvsrbh2Wxo3SebfGb4xVtODMmD2K70',
// where 'Uvsrbh2W' is an encoded, random salt of 6 'raw' bytes

$raw_salt = decode(substr($hash, 4, 8));

$hash = bcrypt_with_custom_salt($hash, $raw_salt . random_bytes(10));

// $hash is now '$2y$12$Uvsrbh2WzN9HrapVpnmu2OYOdJ2jnjHt2LTwIYQPJe.BUJQKezKuO'
// whose salt uses the first 6 bytes we had in phpass,
// so that we can repeat the process when veryfing the password
// since we have all the salts available in only one hash

Escludendo eventuali bug di implementazione e supponendo che le fonti casuali siano crittograficamente sicure, questo è un modo teoricamente sicuro di utilizzare bcrypt in un contesto legacy? Dalla mia comprensione il risultato dovrebbe essere sicuro ( se non di più ...? ) come solo facendo bcrypt(password) , ma non sono un esperto e potrei mancare qualche dettaglio oscuro.

    
posta MM. 23.03.2017 - 13:49
fonte

4 risposte

1

L'involucro unico di PHPass in bcrypt dovrebbe in effetti fornire una significativa resistenza alla bruteforce offline. Come ho commentato sopra, usando i fattori di lavoro predefiniti, hashcat può crackare PHPass fallback md5crypt-style PHPass circa 500 volte più velocemente di bcrypt.

Riutilizzare il sale PHPass interno per l'uso con il bcrypt esterno sembra ragionevole. (Sicuramente sembra migliore di un sale statico!) I tuoi vecchi pacchetti bcrypt non saranno abbastanza casuali - ma solo non casuali relativi all'hash di PHPass interno che non è ancora noto al attaccante .

Poiché ogni bcrypt e PHPass sono ancora salati casualmente rispetto a tutti gli altri hash del loro tipo, la distribuzione di sali fornisce ancora un'ampia resistenza alla forza bruta che i sali dovrebbero avere.

Non riesco a pensare a un modo in cui conoscere il PHPass in anticipo potrebbe fornire ulteriori vantaggi all'attaccante. E anche se fornisce un vantaggio lieve , sarà quasi certamente superato dal costo più elevato di cracking bcrypt.

    
risposta data 23.03.2017 - 18:45
fonte
2

Inizialmente intendevo chiudere questo come duplicato di " perché-is-hashing-a-password-con-multiple-hash-funzioni-inutili " tuttavia si ha un caso leggermente più complesso in quanto si dispone già di un database di password con hash.

Se ritieni che il tuo meccanismo di hashing esistente sia insufficiente rispetto a quello necessario per eseguire la migrazione a una soluzione migliore. Ciò significa che è necessario essere in grado di discriminare tra la vecchia e la nuova rappresentazione, eseguire i meccanismi di verifica in parallelo e convertire il testo chiaro dalla vecchia rappresentazione al nuovo. E l'unica volta che ottieni il testo chiaro è quando qualcuno accede.

Sebbene PHPPass sia piuttosto lungo nel dente, usa blowfish (e bcrypt è basato su blowfish). Quindi forse non stai migliorando la sicurezza quanto pensi.

    
risposta data 23.03.2017 - 14:35
fonte
2

Direi che se ti allontani da phpass vorrai rimuoverlo il più possibile dalla tua base di codice. Potrei suggerire di sostituire prima tutti i phpass con la versione briptata di essi, quindi sostituire l'hash phpass con l'hash bcrypt la prossima volta che un utente effettua l'accesso. Per supportare gli utenti che accedono per la prima volta dallo switch, dovresti anche controllare se il phpass corrisponde.

Quindi qualcosa come la seguente. Ovviamente sto usando pseudo codice in quanto la funzione non è chiamata "bcrypt".

if bcrypt(phpass($supplied_password)) == $storred_password;
    $storred_password = bcrypt($supplied_password);
    login();
if bcrypt($supplied_password) == $storred_password;
    login();

In questo scenario, stai lentamente migrando allo schema della nuova password, ma quello vecchio è ancora supportato.

Se esiste una vulnerabilità in phpass come una perdita di memoria o qualcosa di pazzesco, non lo si utilizza affatto nella maggior parte delle password in quanto gli utenti accedono.

    
risposta data 23.03.2017 - 15:44
fonte
0

Quello che stai facendo è essenzialmente una espansione chiave . Ma phpPass lo fa già (come bcrypt ), quindi quello che stai facendo realmente da un punto di vista della sicurezza sta aumentando (leggermente) la sicurezza aggiungendo un round in più, niente di più.

Potrebbero esserci alcune vulnerabilità di implementazione in phpPass che potrebbero portare alla divulgazione delle chiavi (ad esempio non disinfettando i buffer di memoria), ma le possibilità di sfruttamento sembrano ridotte.

Tutto sommato, direi che non diminuisci la sicurezza, anche se probabilmente non aumenti significativamente.

Anche così, potrebbe essere utile seguire un metodo di migrazione del database. Ad esempio aggiungendo un campo alla tabella utente per contenere un hash di bcrypt puro (o NULL). Se è NULL, viene utilizzato l'algoritmo phpPass e, se la password viene convalidata, viene generato il campo bcrypt. Puoi monitorare la percentuale di campi hash pieni di bcrypt per vedere come procede la migrazione. E puoi azzerare l'hash phpPass di alcuni utenti migrati al test per verificare che tutto funzioni quando si è in bcrypt da solo (se il sistema è progettato in modo pulito questo è superfluo, ma è comunque bello poter mostrare uno scenario Happy Day al CEO: una tabella con coperture del codice non la riduce tanto.

    
risposta data 23.03.2017 - 15:25
fonte

Leggi altre domande sui tag