使用pbkdf2 crypto哈希密码无法正常工作 [英] hashing passwords with pbkdf2 crypto does not work correctly

查看:165
本文介绍了使用pbkdf2 crypto哈希密码无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

密码安全并不是我的强项。请帮助我。



我使用node.js 4.2.3 express 4.13.3。我发现了一些用crypto的pbkdf2来散列和密码的例子。



这是我的代码。

  var salt = crypto.randomBytes(10).toString('base64'); 
console.log(salt>+ salt);
crypto.pbkdf2(pass,salt,10000,150,'sha512',function(err,derivedKey){
pass = derivedKey.toString('hex');
});

最终的derivedKey不包含salt。我错过了什么?我应该在保存之前手动加入这两个字符串吗?



为什么一些示例使用 base64 和其他六角?获得不同的字符串长度?什么是默认值,所以我可以使用它?



为什么不在密码中使用 basic64



最终的derivedKey字符串是UTF8吗?或者这只能与它保存的数据库一起做?我的数据库使用UTF8。



谢谢

解决方案

盐本身,分开,未加密。确保它是随机生成的。

更重要的是,您要求150个字节(每个字节 nodejs.org )的密钥长度 - SHA512是一个绝妙的选择,但它只提供64个字节的本机输出。要获得10,000个150字节输出的迭代, PBKDF2 / RFC2898 将执行30,000次,而离线攻击者只需要运行10,000次迭代并匹配前64个字节(如果前64个匹配,其余的也是); b
$ b

相反,如果您对工作感到满意因此,您应该使用30,000次的64字节输出迭代 - 您将花费相同的时间,没有什么区别,但攻击者现在也必须进行30,000次迭代,因此您可以消除3:1的优势!



当您将salt传递给PBKDF2函数时,如果可以,只需传入纯二进制文件。另外,node.js文档说 - 合理地建议盐是随机的,它们的长度大于16个字节。这意味着二进制的16个字节,在base64或十六进制之前或任何转换,如果你想要一个。



您可以将salt和derivedkey保存为最正确长度的BINARY有效的存储空间(然后您不必担心UTF-x与ASCII),也可以将一个或两个转换为BASE64或十六进制,然后根据需要转换回二进制。 Base64 vs hex与二进制文件无关,只要转换能够根据需要进行转换即可。



我还会将迭代次数存储为一个字段,以便您轻松增加它在未来几年中,包括一个用于版本的密码哈希使用的领域,所以你可以很容易地改变你的算法在未来几年,如果需要的话。


Password security is not my strong suit. Please help me out.

I use node.js 4.2.3 express 4.13.3. I found some examples to hash and salt passwords with crypto's pbkdf2.

Here is my code.

var salt = crypto.randomBytes(10).toString('base64');
console.log("salt  >  "+salt);
crypto.pbkdf2(pass, salt , 10000, 150, 'sha512',function(err, derivedKey) {
    pass = derivedKey.toString('hex');
});

The final derivedKey does not include the salt. What am I missing? Should I join the two strings manually before saving?

Why some examples use base64 and others hex? To get different string lenghts? What is the default, so I can use it?

Why not to use basic64 in both salt and hashed password?

Is the final derivedKey string UTF8? Or this has to do only with the database it gets saved? My database is in UTF8.

Thanks

解决方案

Yes, store the salt yourself, separately, unencrypted. Make sure it's randomly generated.

More importantly, you're crippling your PBKDF2 encryption by asking for 150 bytes (bytes per nodejs.org) of key length - SHA512 is a fantastic choice, but it only provides 64 bytes of native output. To get 10,000 iterations of 150 bytes of output, PBKDF2/RFC2898 is going to execute 30,000 times, while an offline attacker will only need to run 10,000 iterations and match the first 64 bytes (if the first 64 match, then the rest will too); you gave them a 3:1 advantage for free!

Instead, if you're happy with the work factor, you should use 30,000 iterations of 64 bytes of output - you'll spend the same amount of time, no difference, but the attacker now has to do 30,000 iterations too, so you took away their 3:1 advantage!

When you pass the salt to the PBKDF2 function, if you can, just pass in the pure binary. Also, the node.js docs say - reasonably "It is recommended that the salts are random and their lengths are greater than 16 bytes." This means binary 16 bytes, before the base64 or hex or whatever conversion if you want one.

You can save both salt and derivedkey as BINARY of the correct length for the most efficient storage (then you don't have to worry about UTF-x vs. ASCII), or you can convert one or both to BASE64 or hexadecimal, and then convert back to binary as required. Base64 vs hex vs binary is irrelevant as long as the conversions are reconverted as needed.

I'd also make the number of iterations a stored field, so you can easily increase it in the years to come, and include a field for the "version" of password hashing used, so you can easily change your algorithm in the years to come if need be as well.

这篇关于使用pbkdf2 crypto哈希密码无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆