Node.js 密码散列

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14015677/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 16:49:05  来源:igfitidea点击:

Node.js hashing of passwords

node.jssecuritycryptographypasswordspassword-hash

提问by alditis

I am currently using the following for hashing passwords:

我目前使用以下哈希密码:

var pass_shasum = crypto.createHash('sha256').update(req.body.password).digest('hex');

Could you please suggest improvements to make the project safer?

您能否提出改进建议以使项目更安全?

回答by balazs

I use the follwing code to salt and hash passwords.

我使用以下代码对密码进行加盐和散列。

var bcrypt = require('bcrypt');

exports.cryptPassword = function(password, callback) {
   bcrypt.genSalt(10, function(err, salt) {
    if (err) 
      return callback(err);

    bcrypt.hash(password, salt, function(err, hash) {
      return callback(err, hash);
    });
  });
};

exports.comparePassword = function(plainPass, hashword, callback) {
   bcrypt.compare(plainPass, hashword, function(err, isPasswordMatch) {   
       return err == null ?
           callback(null, isPasswordMatch) :
           callback(err);
   });
};

回答by jazeee

bcrypt also can be called synchronously. Sample Coffeescript:

bcrypt 也可以同步调用。示例咖啡脚本:

bcrypt = require('bcrypt')

encryptionUtil = 
    encryptPassword: (password, salt) ->
        salt ?= bcrypt.genSaltSync()
        encryptedPassword = bcrypt.hashSync(password, salt)
        {salt, encryptedPassword}

    comparePassword: (password, salt, encryptedPasswordToCompareTo) ->
        {encryptedPassword} = @encryptPassword(password, salt)
        encryptedPassword == encryptedPasswordToCompareTo

module.exports = encryptionUtil

回答by Sergey Yarotskiy

Also there is bcrypt-nodejs module for node. https://github.com/shaneGirish/bcrypt-nodejs.

还有用于节点的 bcrypt-nodejs 模块。https://github.com/shaneGirish/bcrypt-nodejs

Previously I used already mentioned here bcrypt module, but fall into problems on win7 x64. On the other hand bcrypt-nodejs is pure JS implementation of bcrypt and does not have any dependencies at all.

之前我使用了这里已经提到的 bcrypt 模块,但在 win7 x64 上遇到了问题。另一方面,bcrypt-nodejs 是 bcrypt 的纯 JS 实现,根本没有任何依赖项。

回答by Anand Mainali

You can use the bcrypt-js package for encrypting the password.

您可以使用 bcrypt-js 包来加密密码。

  1. Try npm i bcryptjs
  2. var bcrypt = require('bcryptjs')in top.
  3. To hash a password:
  1. 试试npm i bcryptjs
  2. var bcrypt = require('bcryptjs')在顶部。
  3. 要散列密码:
bcrypt.genSalt(10, function(err, salt) {
    bcrypt.hash("B4c0/\/", salt, function(err, hash) {
        // Store hash in your password DB.
    });
});
  1. To check your password,
  1. 要检查您的密码,
// Load hash from your password DB.
bcrypt.compare("B4c0/\/", hash, function(err, res) {
    // res === true
});

You can visit https://www.npmjs.com/package/bcryptjsfor more information on bcryptjs.

你可以访问https://www.npmjs.com/package/bcryptjs了解更多关于 bcryptjs 的信息。

回答by Nitin Manocha

Try using Bcrypt, it secures the password using hashing.

尝试使用 Bcrypt,它使用散列来保护密码。

bcrypt.hash(req.body.password, salt, (err, encrypted) => {
    user.password = encrypted
    next()
})

Where salt is the cost value which specifies the strength of hashing. While logging in, compare the password using bcrypt.compare method:

其中 salt 是指定散列强度的成本值。登录时,使用 bcrypt.compare 方法比较密码:

 bcrypt.compare(password, user.password, (err, same) => {
      if (same) {
           req.session.userId = user._id
           res.redirect('/bloglist')
      } else {
           res.end('pass wrong')
      }
 })

For more info, refer to this blog: https://medium.com/@nitinmanocha16/bcrypt-and-nodejs-e00a0d1df91f

有关更多信息,请参阅此博客:https: //medium.com/@nitinmanocha16/bcrypt-and-nodejs-e00a0d1df91f

回答by Scott Arciszewski

Bcrypt isn't a bad choice, but there are a few gotchas:

Bcrypt 不是一个糟糕的选择,但有一些问题

  1. It will truncate on NULbytes.
  2. It will truncate after 72 characters. If you're using passphrases, this might weaken your password unexpectedly.
  1. 它将截断NUL字节。
  2. 它将在 72 个字符后截断。如果您使用密码短语,这可能会意外削弱您的密码。

As of October 2019, Argon2idis the optimal choice.

截至 2019 年 10 月,Argon2id是最佳选择。

The preferred way of interfacing with Argon2id is through libsodium (a cryptography library that provides a lot of features). There are several bindings to choose from, but the easiest is probably sodium-plus.

与 Argon2id 交互的首选方式是通过 libsodium(一个提供许多功能的加密库)。有多种绑定可供选择,但最简单的可能是sodium-plus

const SodiumPlus = require('sodium-plus').SodiumPlus;
let sodium;
(async function(){
    if (!sodium) sodium = await SodiumPlus.auto(); // Autoload the backend

    let password = 'Your example password goes here. Provided by the user.';

    // Hashing...
    let hash = await sodium.crypto_pwhash_str(
        password,
        sodium.CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
        sodium.CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
    );
    // You can safely store {hash} in a database.

    // Checking that a stored hash is still up to snuff...
    let stale = await sodium.crypto_pwhash_str_needs_rehash(
        hash,
        sodium.CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
        sodium.CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
    );
    if (stale) {
        // Rehash password, update database
    }

    // Password verification
    let valid = await sodium.crypto_pwhash_str_verify(password, hash);
    if (valid) {
        // Proceed...
    }
})();

The documentation for sodium-pluson Github includes password hashing and storage.

钠加文档在Github包括密码散列和存储。