【问题标题】:Password Hashing with JavascriptNodejs使用 JavascriptNodejs 进行密码散列
【发布时间】:2015-08-17 18:19:11
【问题描述】:

我几乎没有密码保护方面的经验。我在大学里没有上过任何密码学课程,我的数学课程只是简单地涉及了实际的加密算法。不过现在,我想将用户密码存储在数据库中,以创建一种安全的方法来登录我的应用程序。看完this,总结了几点:

  • 密码哈希应该花费大量时间,以防止重复登录尝试并提高安全性。
  • 两个或多个密码可能散列到同一个字符串。

考虑到这一点,我尝试使用jssha 在我的节点服务器上实现密码散列。复制自述文件中的示例:

var jsSHA = require('jssha');
var sha = new jsSHA("SHA-512", "TEXT");
sha.update("password");
var hash = sha.getHash("HEX");

console.log(hash);

我可以为密码字符串创建散列,但这个模块似乎违反了上述两个要点。连续运行该脚本 5 次每次都会创建相同的字符串,甚至使用构造函数中的可选 hashmap 来添加迭代:

var sha = new jsSHA("SHA-512", "TEXT", '{"numRounds" : 4000000}');

散列在微秒内完成,无论我提供给构造函数的轮数是多少。

我真的找不到任何专门在 Javascript/Node 中进行散列的文档。我是在错误地使用模块,还是应该使用其他东西?

【问题讨论】:

  • 第三个参数应该是对象字面量,而不是字符串。
  • 您将在security.stackexchange.com 获得更好的答案。但是,我强烈建议不要使用 SHA-512,因为它在很大程度上被破坏为安全哈希。最先进的是 scrypt,尽管 HMAC-SHA1 也被认为是可接受的选择。
  • 哦,真的……我会调查一下这个密码。
  • 你看过bcrypt吗?看起来 jsSHA 没有任何盐的助手。
  • bcrypt 是 scrypt 的另一个不错的替代品。

标签: javascript node.js password-protection


【解决方案1】:

Node 有一个用于基于散列的键拉伸的内置模块:crypto.pbkdf2

我使用以下函数来创建哈希:

function createHash(password, salt, iterations, hashLength, callback) {
    if(hashLength % 2 !== 0){
        throw new Error("hashLength must be even, because it returns a string of two-character hexadecimal digits.");
    }
    var keyLength = hashLength / 2;
    iterations = iterations || 10000;
    crypto.pbkdf2(password, salt, iterations, keyLength, function(err, bytes){
        var hash = Buffer(bytes, 'binary').toString('hex');
        callback(err, hash);
    });
}

...其中password 是要转换为哈希的文字文本,salt 是要与密码一起存储的随机字符串,iterations 是重复密钥拉伸算法的次数, keyLength 是十六进制哈希字符串的最终长度,callback 将哈希返回给调用代码。

我将迭代和密钥长度与哈希和盐存储在同一数据库行中,而不是在配置中,因此我可以选择在用户更新他或她的密码时加强加密。

crypto 模块还包括一个盐创建方法crypto.randomBytes,我是这样使用的:

function createSalt(saltLength, callback){
    if(saltLength % 2 !== 0){
        throw new Error("saltLength must be even, because it returns a string of two-character hexadecimal digits.");
    }
    var byteLength = saltLength / 2;
    crypto.randomBytes(byteLength, function(err, bytes){
        var salt = Buffer(bytes, 'binary').toString('hex');
        callback(err, salt);
    });
}

免责声明:我也不是密码学家。 :)

【讨论】:

  • 您为什么像其他人建议的那样选择 PBKDF2 而不是 Scrypt、Bcrypt 和 HMAC-SHA1?
  • 因为它是 Node 的默认实现。吸引我的不是它的力量,而是我认为,作为 Node 的内置库,它会得到很好的维护和广泛的测试。它是最强的可用算法吗?可能不是,但其他方案似乎有其他缺点(例如可以说更安全的 scrypt 的高内存使用率)并且对于我的目的来说似乎足够安全。 FWIW,在您作为“标准算法”发布的 Crackstation 文章中,它与 bcrypt 一起被提及。
猜你喜欢
  • 2021-06-04
  • 1970-01-01
  • 2018-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-20
  • 2016-09-19
相关资源
最近更新 更多