2017-02-21 1 views
1

Je crois comprendre qu'une fonction de hachage retournera toujours les mêmes résultats lorsqu'elle reçoit les mêmes données. Mais j'ai utilisé du libsodium (via node-sodium) et ce n'est pas ce qui se passe.Qu'est-ce que je ne comprends pas au sujet du hachage des mots de passe?

J'ai dans mon schéma:

UserSchema.pre('save', function(next) { 
    // declare my variables  
    let user = this, 
     buf = Buffer.alloc(sodium.crypto_pwhash_STRBYTES, 'ascii'), 
     passwordBuf = Buffer.from(user.password, 'ascii'), 
     saltedPassBuf, 
     hash; 
    // only hash the password if it has been modified (or is new) 
    if (!user.isModified('password')) return next(); 
    // generate a salt 
    sodium.randombytes_buf(buf, sodium.crypto_pwhash_STRBYTES, 'ascii'); 
    // add salt to the password 
    saltedPassBuf = Buffer.concat([passwordBuf, buf], 128); 
    // hash it separately multiple times 
    // note, i'm not hashing the hash, 
    // I'm hashing the original buffer to see what happens 
    // this has no application in production 
    hash = sodium.crypto_pwhash_str(saltedPassBuf, sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE, sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE); 
    hash2 = sodium.crypto_pwhash_str(saltedPassBuf, sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE, sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE); 
    hash3 = sodium.crypto_pwhash_str(saltedPassBuf, sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE, sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE); 
    // log it to see what I got -- not for production 
    console.log(hash.toString()); 
    console.log(hash2.toString()); 
    console.log(hash3.toString()); 
    // save the salt and the buffer for authentication 
    user.salt = buf; 
    user.password = hash; 
    next(); 
}); 

Je reçois trois chaînes différentes avec ce code journalisées. par exemple.

$argon2i$v=19$m=32768,t=4,p=1$ayPVQ1X+xNhWmD9S5AUuaw$1mWusk59AebhzOHhl+j5JpvmRI27Pq57XG5zcAB5R4U 
$argon2i$v=19$m=32768,t=4,p=1$PjTYKpfhh1bZh+MV84Y9kA$9+U33nf6efuugsrz15cEKDa5+rAHgYVA5Kqo4F1G3DE 
$argon2i$v=19$m=32768,t=4,p=1$Ii8AErmAFc0na9Yi2OgCkw$ySU80Fv9OiOmeT9EV/BWon1Jjck2Lx23nOeCk0wkMPU 

Maintenant, la première partie de chacun d'entre eux est le même, me faisant partie de la chose mot de passe soumis est le même (puisqu'il est la première partie du tampon qui est haché). Alors peut-être que ce sont des tampons que je ne comprends pas.

Mais si buf reste statique, pourquoi le reste de saltedPassBuff changerait-il?

modifier: n'a pas fini d'écrire quand je accidentellement soumis, sous la direction de terminer la rédaction de la question

Répondre

1

En plus de votre sel la fonction pwhash (les documentations sont minimes) ajoute très probablement son propre sel aléatoire qui est également inclus dans le résultat pour comparaison ultérieure en utilisant crypto_pwhash_str_verify.

Il y a aussi un aspect "CPU intensive", probablement une itération. Juste en utilisant une fonction de hachage avec un sel fait peu pour améliorer la sécurité. Un composant intensif de processeur doit être ajouté tel que l'itération.

Le but est que l'attaquant passe beaucoup de temps à trouver des mots de passe par force brute.

+0

cela s'avère être le cas. Qui réduit également la quantité de code dans ma fonction .pre(). Je pense que je ne vais pas entrer dans la façon dont le libsodium suit le sel ajouté. –

0

Comme le nom fait allusion, la sortie est salée. Cela signifie qu'une chaîne aléatoire a été ajoutée au mot de passe avant le hachage, et également incluse dans la valeur de sortie séparément.

Le but de ceci est de vaincre dictionary attacks. En ajoutant une chaîne aléatoire à chaque mot de passe avant le hachage, vous vous assurez que le même mot de passe sera haché différemment, forçant l'attaquant à déchiffrer chaque mot de passe séparément.

+0

Je ne pense pas que cela réponde à ce que je demande. J'ajoute des données aléatoires via la fonction 'randombytes_buf()' mais cela arrive une fois, et la fonction de hachage consiste à hacher le même ensemble de données chaque fois qu'il s'exécute. À moins que vous ne disiez que 'crypto_pwhash_str()' ajoute aussi des octets aléatoires avant d'exécuter le hachage réel. Est-ce le cas? Si oui, comment authentifiez-vous? –

+0

@Nick Johnson Le sel également les assureurs que deux mots de passe ne pas hachage à la même valeur, laissant ainsi deux utilisateurs ont le même mot de passe. – zaph

+0

@TheE Oui, 'crypto_pwhash_str' ajoute un sel, selon [les docs] (https://download.libsodium.org/doc/password_hashing/the_argon2i_function.html). Vous n'avez pas besoin d'ajouter les vôtres; il est conçu comme une solution complète de hachage de mot de passe. –