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.