2013-10-12 2 views
0

나는 인증 익스프레스의 예를 다음, 사용자의 암호를 해시 다음과 같은 기능을 사용하고 있습니다 :mongoDB에 crypto pbkdf2를 저장하는 방법은 무엇입니까?

salt
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); 
      }); 
     }); 
    } 
} 

, 당신이 볼 수는 base64로 인코딩 된 문자열로 반환됩니다. 그러나 hashSlowBuffer으로 반환됩니다. 이 동일한 함수는 사용자를 로그인 할 때 해시를 비교하는데도 사용됩니다.

사용자에 대한 내 몽구스 스키마는 이어야 함을 지정합니다. 이것은 내 몽고 호스트에 대혼란이 같은 내용의 결과로, 이상한 방법으로 해시를 저장하지 끝 :

screenshot of hash in mongodb

내 질문은,이 hash를 저장하는 더 나은/현명한 방법이 내 데이터 베이스? 나는 .toString('hex')으로 인코딩을 시도했는데 으로 사용자 스키마의 hash 유형을 변경해 보았습니다.하지만이 두 접근법은 사용자를 로그인 할 때 모든 비교를 false로 만들었습니다. 내 authenticate 함수에서 비교가 이루어졌습니다.

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')); 
     }); 
    }); 
    }); 
}); 

(아래 : 데이터베이스의 16 진수 문자열이 나에게 괜찮 작동하기 때문에 해시를 저장

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.'); 
    }); 
} 
+0

어떻게 실제 비교를 수행합니까? 코드를 보여줄 수 있습니까? – robertklep

+0

@robertklep가'authenticate' 함수를 추가하도록 편집되었습니다.이 함수는 비교를 수행합니다 – Jakemmarsh

답변

1

(에서 중 하나 String 또는 Buffer 재산하지 않습니다를 저장하는 '원시') 그런데 crypto.pbkdf2crypto.randomBytes 모두 동기 카운터 파트)

+0

이것은 효과가있었습니다. 전에 이것을 시도했을 때 사용자를 기록하려고 시도 할 때'toString ('hex')'을 호출하지 말았어야합니다. 또한 동기식 사본이 있다는 것을 알고 있습니다. 앱의 다른 부분에서 사용합니다. 고맙습니다! – Jakemmarsh

관련 문제