2017-06-02 20 views
0

has_secure_passwordをRailsモデルに追加すると、暗号化に問題があるかどうかは完全にはわかりません。私は間違いなく塩でハッシュしていることを知っていますが、そこに暗号化がありますか? bcryptはフクロウを使うことができますが、bcrypt-ruby(これの背後にある宝石)に使われていますか?has_secure_password - ハッシュまたは暗号化のみですか?

答えて

1

TL; has_secure_passwordは、self.password=メソッドを使用するときにBcryptのハッシュ関数を使用するようにします。


のはhas_secure_passwordのコードを見てみましょう:

# File activemodel/lib/active_model/secure_password.rb, line 53 
    def has_secure_password(options = {}) 
     # Load bcrypt gem only when has_secure_password is used. 
     # This is to avoid ActiveModel (and by extension the entire framework) 
     # being dependent on a binary library. 
     begin 
     require "bcrypt" 
     rescue LoadError 
     $stderr.puts "You don't have bcrypt installed in your application. Please add it to your Gemfile and run bundle install" 
     raise 
     end 

     include InstanceMethodsOnActivation 

     if options.fetch(:validations, true) 
     include ActiveModel::Validations 

     # This ensures the model has a password by checking whether the password_digest 
     # is present, so that this works with both new and existing records. However, 
     # when there is an error, the message is added to the password attribute instead 
     # so that the error message will make sense to the end-user. 
     validate do |record| 
      record.errors.add(:password, :blank) unless record.password_digest.present? 
     end 

     validates_length_of :password, maximum: ActiveModel::SecurePassword::MAX_PASSWORD_LENGTH_ALLOWED 
     validates_confirmation_of :password, allow_blank: true 
     end 
    end 

我々はそれがハッシュ/何かを暗号化しないことがわかります。それにもかかわらず、私たちは気づく:

私たちは、次のコードを取得 InstanceMethodsOnActivationのドキュメントに行けば
 include InstanceMethodsOnActivation 

def password=(unencrypted_password) 
    if unencrypted_password.nil? 
    self.password_digest = nil 
    elsif !unencrypted_password.empty? 
    @password = unencrypted_password 
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost 
    self.password_digest = BCrypt::Password.create(unencrypted_password, cost: cost) 
    end 
end 

。したがって、has_secure_passwordは暗号化されません/ハッシュ何でもしかしInstanceMethodsOnActivationモジュールを含んでいます。このモジュールはpassword=メソッドを定義します。この方法の重要な部分がある:

self.password_digest = BCrypt::Password.create(unencrypted_password, cost: cost) 

は、今度はBCrypt::Password.createのコード見に行こう:この方法では

def create(secret, options = {}) 
    cost = options[:cost] || BCrypt::Engine.cost 
    raise ArgumentError if cost > 31 
    Password.new(BCrypt::Engine.hash_secret(secret, BCrypt::Engine.generate_salt(cost))) 
    end 

    def valid_hash?(h) 
    h =~ /^\$[0-9a-z]{2}\$[0-9]{2}\$[A-Za-z0-9\.\/]{53}$/ 
    end 
end 

を、私たちは特に注意してください:

Password.new(BCrypt::Engine.hash_secret(secret, BCrypt::Engine.generate_salt(cost))) 

だから、そうです論理的です(あなたはパスワードをとにかく解読したくありません)。

関連する問題