2011-08-05 14 views
69

node.js ve mongodb kullanarak şifreleri ve diğer hassas verileri güvenli bir şekilde nasıl saklayacağınıza dair bazı örnekler arıyorum.Node.js ve MongoDB ile şifrelerin saklanması

Herşeyin mongo belgesinde karma saklayacağım benzersiz bir tuz kullanmasını istiyorum.

Doğrulama için girdiyi tuzlamanız ve şifrelemek ve depolanmış bir hash ile eşleştirmek zorunda mıyım?

Bu verilerin şifresini çözmem gerekir mi? Öyleyse nasıl yapmalıyım?

Sunucuda özel anahtarlar, hatta tuzlama yöntemleri nasıl güvenli bir şekilde depolanır?

AES ve Blowfish'in iyi bir seçenek olduğunu duydum, ne kullanmalıyım?

Bunu nasıl tasarlayacağınıza dair her şey harika bir şekilde yardımcı olabilir!

Teşekkürler!

+0

olası yinelenen http://stackoverflow.com/questions kullanır/615704/veritabanı içinde tercih edilen yöntem-depolama-şifreleri) – Thilo

+0

https://github.com/bnoguchi/mongoose-auth/? – Alfred

cevap

35

bunu kullanın: https://github.com/ncb000gt/node.bcrypt.js/

bcrypt bu kullanım şeklini odaklanmış birkaç algoritmalardan biridir. Şifrelerinizin şifresini asla çözemezsiniz, sadece kullanıcı tarafından girilen bir cleartext şifresinin saklanan/şifreli karma ile eşleştiğini doğrulamamalısınız.

bcrypt kullanımı oldukça kolaydır. İşte Mongoose Kullanıcı şemasından bir kod parçacığı (CoffeeScript'te). Bycrypt yavaş (amaç) olarak async işlevlerini kullandığınızdan emin olun.

class User extends SharedUser 
    defaults: _.extend {domainId: null}, SharedUser::defaults 

    #Irrelevant bits trimmed... 

    password: (cleartext, confirm, callback) -> 
    errorInfo = new errors.InvalidData() 
    if cleartext != confirm 
     errorInfo.message = 'please type the same password twice' 
     errorInfo.errors.confirmPassword = 'must match the password' 
     return callback errorInfo 
    message = min4 cleartext 
    if message 
     errorInfo.message = message 
     errorInfo.errors.password = message 
     return callback errorInfo 
    self = this 
    bcrypt.gen_salt 10, (error, salt)-> 
     if error 
     errorInfo = new errors.InternalError error.message 
     return callback errorInfo 
     bcrypt.encrypt cleartext, salt, (error, hash)-> 
     if error 
      errorInfo = new errors.InternalError error.message 
      return callback errorInfo 
     self.attributes.bcryptedPassword = hash 
     return callback() 

    verifyPassword: (cleartext, callback) -> 
    bcrypt.compare cleartext, @attributes.bcryptedPassword, (error, result)-> 
     if error 
     return callback(new errors.InternalError(error.message)) 
     callback null, result 

Ayrıca this article, which should convince you that bcrypt is a good choice okuyun ve "iyi ve gerçekten effed" olmaktan kaçınmak yardımcı olur.

+1

Ben bcrypt kullanarak mantığa satın aldığımdan% 100 emin değilim, çünkü makale notları gibi yavaş. SHA-256 gibi çok daha fazla "standart" ve yaygın olarak kullanılan bir algoritma kullanmanın ve sisteminizde yapay gecikme uygulamanıza gerek yok. Sadece sunucunun geçtiği hash değerini kontrol etmeden önce saniyenin dörtte birini bekleyin. Bazı sistemler, şifreleri y saat içinde x kez yanlış alırlarsa bir kullanıcı kilitleme (veya azaltılmış ayrıcalık) protokolü de uygulamaktadırlar. Bu belirli bir bagajla birlikte geliyor, ama dikkate alınması gereken bir seçenek. – d512

+18

Noktayı kaçırıyorsunuz. Bir saldırgan şifreli karma veri tabanınızı çalıyorsa, saldırganın kendi sistemlerinde çalışması için bcrypt yavaştır ve bunun bir yolu yoktur çünkü iş faktörü algoritmanın kendisinde yerleşiktir. SHA-256 artı yapay gecikme, A) genel amaçlı bir karma algoritma ve B) çalınan parola karmalarının çevrimdışı çatlamasına karşı sizi korumaz. –

+0

Evet, saldırganın aslında tüm parola karelerinin bir kopyasını alabildiği bir senaryoda, onları bcrypt altında kırmanın daha zor bir zamanları olurdu. Makale, özellikle bu durumdan bahsetmiyor ama muhtemelen yapmalı. – d512