使用crypto的Node.js密码哈希bcrypt替代方案

时间:2014-04-02 18:22:49

标签: javascript node.js passwords cryptography bcrypt

我实际上正在使用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);

4 个答案:

答案 0 :(得分:8)

您可以使用加密库中的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)从给定的密码,salt和迭代中导出给定长度的密钥。 Pbkdf2具有类似bcrypt的慢速特征。使用PBKDF2,bcrypt或scrypt,攻击者每秒只能进行几千次猜测(或更少,具体取决于配置)。

答案 1 :(得分:3)

bcrypt比crypto更安全,因为它更慢。但是,以下是我在coffeescript中使用加密编写的一些密码函数(我将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)

答案 2 :(得分:2)

2020年4月24日起,在scrypt模块中使用crypto建立了一种很好的散列密码的内置方式。它非常安全,因为它利用来对密码进行散列,并且基于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 个字符,但是您可以指定所需的长度

答案 3 :(得分:0)

bcryptjs的另一种选择。 该概念与bcrypt相同,但没有依赖关系,并且与bcrypt兼容。

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

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