如何在 mongoDB 中存储加密 pbkdf2? [英] How to store crypto pbkdf2 in mongoDB?

查看:50
本文介绍了如何在 mongoDB 中存储加密 pbkdf2?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下函数来散列用户的密码,遵循 Express 的身份验证示例:

I'm using the following function to hash a user's password, following Express's example for authentication:

function hash(pwd, salt, fn) {
    // Bytesize
    var len = 128,

    // Iterations. ~300ms
        iterations = 12000;

    if (3 == arguments.length) {
        crypto.pbkdf2(pwd, salt, iterations, len, fn);
    } else {
        fn = salt;
        crypto.randomBytes(len, function(err, salt){
            if (err) return fn(err);
            salt = salt.toString('base64');
            crypto.pbkdf2(pwd, salt, iterations, len, function(err, hash){
                if (err) return fn(err);
                fn(null, salt, hash);
            });
        });
    }
}

salt,如您所见,以 base64 编码的字符串形式返回.但是,hash 作为 SlowBuffer 返回.当尝试登录用户时,该函数也用于比较哈希值.

The salt, as you can see, is returned as a string encoded in base64. The hash, however, is returned as a SlowBuffer. This same function is also used to compare hashes when trying to log a user in.

My Mongoose schema for Users 指定 hash 应该是 String 类型.这最终以一种奇怪的方式存储散列,导致这样的内容对我的 mongo 主机造成了严重破坏:

My Mongoose schema for Users specifies that the hash should be of type String. This ends up storing the hash in a strange way, resulting in contents like this which wreaked havoc on my mongo host:

我的问题是,是否有更好/更智能的方法来将此 hash 存储在我的数据库中?我尝试使用 .toString('hex') 对其进行编码,并且我还尝试将 User 架构中的 hash 类型更改为 buffer,但是当尝试登录用户时,这两种方法都使所有比较都为假.比较是在我的 authenticate 函数中进行的,如下所示:

My question is, is there a better/smarter way to store this hash in my database? I've tried encoding it with .toString('hex'), and I've also tried changing the hash type in the User schema to buffer, but both these approaches made all comparisons false when trying to log users in. Comparisons are made in my authenticate function, seen below:

function authenticate(name, pass, fn) {
    var findUser = function(username) {
        var deferred = Q.defer(),
            populateObj = [
                // list of paths to populate objects normally goes here
            ];
        User.findOne({ username: name }).populate(populateObj).exec(function (err, retrievedUser) {
            if (err || !retrievedUser) {
                console.log(err);
                deferred.reject('Cannot find user.');
            }
            else {
                deferred.resolve(retrievedUser);
            }
        });

        return deferred.promise;
    };

    findUser(name).then(function(data) {
        // apply the same algorithm to the POSTed password, applying
        // the hash against the pass / salt, if there is a match we
        // found the user
        hash(pass, data.salt, function(err, hash){
            if (err) return fn(err);
            if (hash == data.hash) return fn(null, data);
            return fn('Invalid password.');
        });
    }, function() {
        return fn('Failed to retrieve user.');
    });
}

推荐答案

将哈希作为十六进制字符串存储在数据库中对我来说工作正常(将它们原始"存储在 StringBuffer 属性没有):

Storing the hash as a hex string in the database works okay for me (storing them 'raw' in either a String or a Buffer property doesn't):

var crypto      = require('crypto');
var mongoose    = require('mongoose');
var client      = mongoose.connect('mongodb://localhost/test');
var UserSchema  = new mongoose.Schema({
  salt  : String,
  hash  : String
});

var User = mongoose.model('User', UserSchema);

hash('secret', function(err, salt, key) {
  new User({ salt : salt, hash : key.toString('hex') }).save(function(err, doc) {
    User.findById(doc._id, function(err, doc) {
      hash('secret', doc.salt, function(err, key) {
        console.log('eq', doc.hash === key.toString('hex'));
      });
    });
  });
});

(顺便说一下,crypto.pbkdf2crypto.randomBytes 都有同步副本)

(by the way, both crypto.pbkdf2 and crypto.randomBytes have synchronous counterparts)

这篇关于如何在 mongoDB 中存储加密 pbkdf2?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆