【问题标题】:Node.js password hashing bcrypt alternative using crypto使用加密的 Node.js 密码散列 bcrypt 替代方案
【发布时间】:2014-05-14 05:34:59
【问题描述】:

我实际上是在使用bcrypt 模块来散列和比较散列密码。

我想要做的是删除bcrypt 模块并使用默认的crypto 库来哈希和比较密码。

这可能吗?

这会比使用node-bcrypt 更安全吗?

你有任何关于如何做的例子/教程/文档/链接吗?

或者我实际上是这样做的:

bcrypt.hash(string,secret_key)
bcrypt.compare(string,string,secret_key);

如果可能的话,我只是想用加密来复制它:

crypto.hash(string,secret_key)
    crypto.compare(string,string,secret_key);

【问题讨论】:

    标签: javascript node.js passwords cryptography bcrypt


    【解决方案1】:

    bcrypt 将比加密更安全,只是因为它更慢。然而,这里有一些我在coffeescript中使用crypto编写的密码函数(我用'$'加入create_password部分,你会看到check_password中的分割):

      create_password = function(passwd, method, salt) {
        var hmac;
        method || (method = "sha1");
        salt || (salt = crypto.randomBytes(6).toString('base64'));
        hmac = crypto.createHmac(method, salt);
        hmac.end(passwd);
        return {
          hash: hmac.read().toString('hex'),
          salt: salt,
          method: method
        };
      };
    
      check_password = function(hashed, passwd) {
        var hash, hashp, method, salt, _ref;
        _ref = hashed.split("$"), method = _ref[0], salt = _ref[1], hashp = _ref[2];
        hash = create_password(passwd, method, salt).hash;
        return hash === hashp;
      };
    

    示例用法:

    passwd = "SOME STRING HERE"
    hash_parts = create_password(passwd)
    hashed = pwd_parts.method + "$" + pwd_parts.salt + "$" + pwd_parts.hash
    check_password(hashed, passwd)
    

    【讨论】:

    • 是的,它是以这种方式存储的遗留系统,我的应用程序不需要任何超级安全的东西。不过显然是可配置的!
    • +1 为帮助,谢谢,但我更喜欢上面的其他建议在我的情况下更好:)
    【解决方案2】:

    您可以使用加密库中的 pbkdf2 进行哈希处理:

    crypto.pbkdf2(password, salt, iterations, keylen, digest, callback)
    

    示例实现:

    const crypto = require('crypto');
    crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', (err, derivedKey) => {
      if (err) throw err;
      console.log(derivedKey.toString('hex'));  // '3745e48...aa39b34'
    });
    

    这里是参考:https://nodejs.org/api/crypto.html#crypto_crypto_pbkdf2_password_salt_iterations_keylen_digest_callback

    它使用 HMAC 摘要算法(如 sha512)从给定的密码、盐和迭代中导出给定长度的密钥。 pbkdf2 具有类似 bcrypt 的缓慢特性。使用 PBKDF2、bcrypt 或 scrypt,攻击者每秒只能进行几千次猜测(或更少,取决于配置)。

    【讨论】:

    • 请注意,使用oclHashcat with GPU's 或类似工具的攻击者每秒可以进行比您更多的猜测,除非您真的加快了迭代速度。例如,具有 8x AMD R9 290Xstock 核心时钟的单台 PC 每秒可以进行或多或少 130 万次 PBKDF2-HMAC-SHA-1(password,salt,8192,20) 测试,即每 30 次猜测 3.4E12 或 2^41天。你必须增加你的迭代次数(或 BCrypt 工作系数)才能更多地塑造他们的风格。
    • @Anti-weakpasswords 是的,cpu 和 gpu 的速度一直在提升,这就是为什么你在 pbkdf2 中有可配置的迭代,所以你可以始终保持平衡
    • @Masum,另请注意,如果您可以在 64 位系统上使用 PBKDF2-HMAC-SHA-384 或 PBKDF2-HMAC-SHA-512,则可以减少 GPU 的优势余量基于攻击者的攻击,因为当前一代 GPU 在 SHA-384 和 SHA-512 所需的 64 位操作方面不如 32 位操作好。
    • 如何验证密码?我需要将盐显式存储在数据库中,然后再运行相同的东西?
    • 你们有没有人能够在 Centos 5 系统上实现这个功能?我在本地有这个功能,但在我的远程盒子上它会抛出一个错误crypto.pbkdf2('secret', 'buf', 1028, 64, 'sha256', function(err, key) {...}); ^ TypeError: Bad parameter
    【解决方案3】:

    bcryptjs 的替代方案。 概念与bcrypt相同,但没有依赖关系,兼容bcrypt。

    https://github.com/dcodeIO/bcrypt.js

    https://www.npmjs.com/package/bcryptjs

    【讨论】:

      【解决方案4】:

      截至 2020 年 4 月 24 日crypto 模块中使用 scrypt 提供了一种很好的内置哈希密码方法。它非常安全,因为它使用 salt 来散列密码及其基于 scrypt

      // built right into nodejs
      const crypto = require("crypto");
      
      // salt - any random string here (ideally should be above 16 bytes)
      const salt = "EoAZAJtVDdzPZmOxpx0EnqLmREYUfq";
      function getHash() {
        return crypto.scryptSync("your-password-here", salt, 32).toString("hex");
      }
      

      注意:我使用了 32 个字符的长度,但您可以指定所需的长度

      【讨论】:

      • 1- "crypto.scryptSync" 是否与 "crypto.pbkdf2Sync" 相同? -------------------------------------------------- ---------------- 2- “crypto.scryptSync” 比 “bcrypt” 或 “node.bcrypt.js” 好? -------------------------------------------------- -------- 3-我们是否需要创建和使用静态盐才能使用 crypto.scryptSync ?这安全吗?
      • 1.不,它们都是不同的算法。 2. 是的,它基于出色的 'scrypt' 算法,仅次于 argon,通常比旧的 bcrypt 算法更好 3. salt 应该是静态的(不能是动态的),因为您需要相同的 salt 来解码散列密码(因此建议使其更强大)并使其安全(最好在环境变量中)
      • 非常感谢。 “crypto.scryptSync”和“crypto.pbkdf2Sync”有什么区别?哪个更好?
      • @Kiax 他们在后台使用不同的算法(scrypt,pbkdf2),但它们都同样出色(django 使用 pbkdf2)。
      猜你喜欢
      • 2019-07-20
      • 1970-01-01
      • 1970-01-01
      • 2021-06-04
      • 2019-07-17
      • 2014-06-09
      • 1970-01-01
      • 1970-01-01
      • 2015-10-08
      相关资源
      最近更新 更多