Node.js хэширование паролей

В настоящее время я использую следующее для хеширования паролей:

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

Не могли бы вы предложить улучшения, чтобы сделать проект более безопасным?


person alditis    schedule 23.12.2012    source источник
comment
Несолёный SHA небезопасен. Используйте бкрипт.   -  person SLaks    schedule 24.12.2012
comment
Спасибо за комментарий, возьму проверю.   -  person alditis    schedule 24.12.2012


Ответы (7)


Я использую следующий код для соления и хеширования паролей.

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);
   });
};
person balazs    schedule 24.12.2012
comment
Не используйте else после возврата, это просто не имеет смысла. Ваше здоровье! - person brielov; 27.01.2014
comment
Не могли бы вы добавить ссылку на библиотеку bcrypt, которую вы используете (если возможно, на github)? Спасибо. - person Tadej; 05.04.2017
comment
@Tadej это было так давно, но я полагаю, что это: npmjs.com/package/bcrypt - person balazs; 09.05.2017
comment
Спасибо. Я даже не проверил дату. Извиняюсь. :/ - person Tadej; 09.05.2017
comment
Есть два модуля: bcrypt и bcryptjs для этой цели. Если кто-то может рассказать больше об этих двух, было бы неплохо. - person Gagan; 15.01.2021

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
person jazeee    schedule 25.06.2014

Также есть модуль bcrypt-nodejs для node. https://github.com/shaneGirish/bcrypt-nodejs.

Ранее я использовал уже упомянутый здесь модуль bcrypt, но на win7 x64 возникли проблемы. С другой стороны, bcrypt-nodejs — это чистая JS-реализация bcrypt, не имеющая вообще никаких зависимостей.

person Sergey Yarotskiy    schedule 03.12.2014
comment
Было бы неплохо, но это больше не поддерживается. - person Stephan Ahlf; 02.01.2018

Вы можете использовать пакет bcrypt-js для шифрования пароля.

  1. Попробуйте npm и 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. Чтобы проверить пароль,
// Load hash from your password DB.
bcrypt.compare("B4c0/\/", hash, function(err, res) {
    // res === true
});

Дополнительную информацию о bcryptjs.

person Anand Mainali    schedule 13.01.2019

Попробуйте использовать Bcrypt, он защищает пароль с помощью хеширования.

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

Где соль — это стоимость, которая определяет силу хеширования. При входе сравните пароль с помощью метода bcrypt.compare:

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

Для получения дополнительной информации обратитесь к этому блогу: https://medium.com/@nitinmanocha16/bcrypt-and-nodejs-e00a0d1df91f

person Nitin Manocha    schedule 18.07.2019

bcrypt с машинописным текстом

npm i bcrypt
npm i -D @types/bcrypt
 import * as bcrypt from 'bcrypt';

export const Encrypt = {

    cryptPassword: (password: string) =>
        bcrypt.genSalt(10)
        .then((salt => bcrypt.hash(password, salt)))
        .then(hash => hash),
    
        comparePassword: (password: string, hashPassword: string) =>
            bcrypt.compare(password, hashPassword)
            .then(resp => resp)
    
    }

Пример: зашифровать

const myEncryptPassword = await Encrypt.cryptPassword(password);

Пример: Сравните

const myBoolean = await Encrypt.comparePassword(password, passwordHash);
person Arthur Cabral    schedule 08.06.2021

Bcrypt — неплохой выбор, но есть несколько ошибок:

  1. Он будет усечен на NUL байт.
  2. Он будет обрезан после 72 символов. Если вы используете парольные фразы, это может неожиданно ослабить ваш пароль.

По состоянию на октябрь 2019 г. оптимальным выбором является Argon2id.

Предпочтительный способ взаимодействия с 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...
    }
})();

документация для натрия-плюс на Github включает хеширование и хранение паролей.

person Scott Arciszewski    schedule 12.10.2019