1

我的理解是,当输入相同的数据时,哈希函数将始终返回相同的结果。但我一直在使用 libsodium(通过 node-sodium),但事实并非如此。

我的架构中有这个:

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();
});

我用该代码记录了三个不同的字符串。例如

$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

现在每一个的第一部分都是相同的,这让我觉得提交的密码部分是相同的(因为它是被散列的缓冲区的第一部分)。所以也许这是我不明白的缓冲区。

但如果buf保持静止,为什么其余部分会saltedPassBuff发生变化?

编辑:我不小心提交的时候还没有写完,编辑完成写完问题

4

2 回答 2

1

除了您的盐之外,该pwhash功能(文档很少)很可能还添加了自己的随机盐,该盐也包含在结果中以供以后使用crypto_pwhash_str_verify.

还有一个“CPU密集型”方面,可能是一个迭代。仅使用带盐的哈希函数对提高安全性几乎没有任何作用。需要添加 CPU 密集型组件,例如迭代。

关键是让攻击者花费大量时间通过蛮力寻找密码。

于 2017-02-21T13:26:14.190 回答
0

顾名思义,输出是加盐的。这意味着在散列之前将随机字符串添加到密码中,并且还单独包含在输出值中。

这样做的目的是击败字典攻击。通过在散列之前为每个密码添加一个随机字符串,您可以确保相同的密码以不同的方式散列,从而迫使攻击者分别破解每个密码。

于 2017-02-21T12:57:42.273 回答