使用pbkdf2 crypto哈希密码无法正常工作

密码安全不是我的强项。 请帮我一下

我使用node.js 4.2.3 express 4.13.3。 我发现一些例子来encryption密码和密码的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。 我错过了什么? 我应该在保存之前手动join两个string吗?

为什么一些例子使用base64和其他的hex ? 获得不同的string长度? 什么是默认的,所以我可以使用它?

为什么不在salt和哈希密码中使用basic64

最终的derivedKeystring是UTF8吗? 或者只有在数据库被保存的情况下才能做到这一点? 我的数据库是UTF8。

谢谢

是的,你自己储存盐,分开,不encryption。 确保它是随机生成的。

更重要的是,通过要求密钥长度为150个字节(每个nodejs.org的字节数),您正在削弱您的PBKDF2encryption – SHA512是一个绝妙的select,但它只提供64个字节的本机输出。 要获得150个字节的输出10,000次迭代, PBKDF2 / RFC2898要执行30,000次,而离线攻击者只需要运行10000次迭代并匹配前64个字节(如果前64个匹配,其余的也是) ; 你给他们免费的3:1优势!

相反,如果你对工作因素感到满意,你应该使用30000次64字节的输出 – 你将花费相同的时间,没有什么区别,但是攻击者现在也必须做3万次迭代,所以你花了远离他们的3:1优势!

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

您可以将salt和derivedkey都保存为最有效存储的正确长度的BINARY(然后您不必担心UTF-x与ASCII),也可以将一个或两个转换为BASE64或hex,然后根据需要转换回二进制。 只要转换根据需要被转换,Base64与hex与二进制是不相关的。

我也会把迭代的次数作为一个存储的字段,所以你可以很容易地在今后几年增加它,并且包括一个用于“版本”的密码哈希使用的字段,所以你可以很容易地改变你的algorithm在几年如果需要的话也可以来。

encryption处理数据,而不是string,这包括encryption密钥。 PBKDF2产生一个数据键,它可以很容易地转换成一个string,这种转换是必要的,因为许多数据字节没有相应的打印字符或unicode代码点。 许多脚本语言不能很好地处理数据,因此数据被多次转换为Base64或hex(hex)。

您可以使用Base64或hex为盐和哈希密码,只是在所有的用途一致。

salt和迭代计数需要与创build检查相同,您需要将它们合并或单独保存。

你的代码是将派生的密钥转换为hex,这很好,base64也可以。 再次这是必要的,因为不是所有的数据字节都是UTF-8。