Qual è il modo corretto per rendere salata una password?

1

Ho creato la funzione qui sotto per creare un hash lungo 64 caratteri completamente casuale

   function password_salt($password){
    $salt = hash("sha512", mt_rand(1,100000) . strtotime("now") . $password . "ewuwmeqwjkeq 7689" . hash("sha256", strtotime("now - 10 days") . $password));
    $salt = $salt . $password;
    for ($i=0;$i<10000;$i++){
        $salt = hash("sha512",$salt);
    }
    $hash = $salt . $password;
    for ($i=0;$i<10000;$i++){
        $hash = hash("sha512",$hash);
    }
    $salt = hash("sha512", mt_rand(1,100000) . strtotime("now") . $password . $hash . "ewuwmeqwjkeq 7689" . hash("sha256", strtotime("now - 10 days") . $hash . $salt) . $salt);

    //salt is almost ready for production
    // go salt part 2
    $salt2 = hash("sha512", $salt . $salt . $salt . $password . mt_rand(1,100000) . "dsjdj3y87Yhuu(&^TYUGh" . hash("sha512", $salt . $salt . $password . $salt));

    //hash salt . salt2 . salt . salt2 . salt2 . hash salt2 timestamp
    $salt = hash("sha512", $salt . $salt2 . uniqid(rand(), true) . $salt . $salt2 . $salt2 . hash("sha512", $salt2 . strtotime("now")));

    // go salt 3
    $salt3 = hash("sha512", $salt2 . $salt . $salt2 . $password . mt_rand(1,100000) . "DMDJ3908_))O l;[h" . hash("sha512", $salt . $salt2 . $password . $salt2));

    //final salt
    $salt = hash("sha512", $salt3 . $salt2 . $salt . $salt2 . $salt3 . hash("sha512", $salt3 . strtotime("now - 1 day") . uniqid(rand(), true)) . uniqid(rand(), true));

    echo "Salt: ". $salt . "<br><br>";
}

Questa funzione è abbastanza buona da rendere salato sicuro?

    
posta Ben Johnson mk2 23.02.2014 - 18:11
fonte

3 risposte

6

Con un approccio indipendente dalla lingua, si consiglia vivamente di utilizzare tecniche ben testate e testate nel tempo per hash sicuro delle tue password (o di eventuali problemi relativi alla crittografia, per quello che riguarda) invece di venire con il tuo.

Perché? Perché tu, per definizione, sei un cervello. Il più delle volte, un cervello non prende i propri errori finché non è troppo tardi. Tre cervelli sono migliori e quattro ancora meglio. Tali librerie possono avere tra le decine e le migliaia di persone che lavorano su di esse e / o cercano di romperle.

Dato che usi PHP, ti consiglio di utilizzare librerie con poca curva di apprendimento e fanno tutto per te (generando sale, hashing e verifica) come PHPass . Se hai il lusso di codificare solo per PHP 5.5, puoi utilizzare la stessa API di PHP (controlla password_hash ).

Infine, per rispondere direttamente alla tua domanda, se vuoi semplicemente generare una stringa esadecimale di 64 caratteri (un gigantesco 256 bit), ti consiglio di usare qualcosa di simile:

$salt = bin2hex(openssl_random_pseudo_bytes(32));

Nota: Mentre 256-bit è fantastico, penso che sia un po 'troppo per un sale. Raccomando di andare con 128 bit (16 byte), che produrrà una stringa esadecimale di 32 caratteri.

    
risposta data 23.02.2014 - 19:16
fonte
3

In primo luogo, come ogni altra risposta ha menzionato e senza dubbio menzionerà, leggi Come fare in modo sicuro le password di hash? e forse anche il racconto cautelativo di non essere un Dave .

Per rispondere alla domanda attuale, per generare un salt, usa semplicemente un ben noto generatore di numeri pseudocasuali crittograficamente sicuro per molti byte che desideri di output binario. L'hashing di un PRNG non crittografato non lo rende di per sé un CSPRNG (vedi L'hashing di un PRNG lo rende crittograficamente sicuro? ).

Sia che tu finisca per usare PBKDF2, Bcrypt o Scrypt, il processo di hashing della password funziona su valori binari, quindi un binario sale ti dà la più casualità per byte di memoria, ovvero puoi memorizzare 8 byte di dati binari, oppure Stringa da 16 byte che codifica quegli stessi 8 byte di dati binari in esadecimale (ecc.). Ogni metodo di archiviazione diverso da binario occupa spazio aggiuntivo.

Ovviamente puoi usare altre codifiche - segui qualsiasi implementazione nota che hai scelto.

Alcuni esempi di CSPRNG trovati da una ricerca di Google su "crypto RNG [language]" includono:

Nota che potresti voler fare ulteriori ricerche sulle versioni Perl e Ruby, dato che non ho cercato conferme di terze parti, e i PRN di crittografia sono difficili da validare (vedi il racconto di ammonimento di Dual_EC_DRBG in NIST SUPPLEMENTAL ITL BULLETIN PER SETTEMBRE 2013

    
risposta data 24.02.2014 - 01:31
fonte
-1

Stai utilizzando SHA-512, che non è raccomandato per i sali. Piuttosto che scrivere la tua logica per iterarlo ripetutamente, e magari rovinarlo (che è incredibilmente facile da fare), dovresti usare bcrypt (o qualcosa di simile). Guarda la risposta a questa domanda .

    
risposta data 23.02.2014 - 18:20
fonte

Leggi altre domande sui tag