Skip to content

Using Bcrypt for authentication

leucos edited this page Oct 14, 2012 · 2 revisions

You probably know how to use Authentication in your application already. It only takes a few lines of code to secure your password handling. Using BCrypt is a good way to improve password security on your site.

First, by using BCrypt, you don't store passwords in clear anymore. If your database gets stolen, the passwords are can't be recovered. Also, by using BCrypt hashing, you need a certain amount of CPU power to compute hashes, and you can adjust the level of computing needed, to match hardware performance increase. This makes your application less vulnerable to brute force attacks.

This being said, it's quite straightforward to set-up, so there's no reason to go without BCrypt.

Add bcrypt-ruby to you Gemfile (or install it).

Let's assume your users table has a login and password_hash fields.

class User < Sequel::Model
  # Mix in BCrypt module
  include BCrypt
  
  def password
    # Initialize a BCrypt::Password instance from hashed password
    @password ||= Password.new(password_hash)
  end

  # This creates a hashed password from a clear text password
  # The hashed password is then stored in the password_hash member
  # that will be written to the database
  def password=(new_password)
    @password = Password.create(new_password)
    self.password_hash = @password
  end

  def self.authenticate(creds)
    Ramaze::Log.info("Login attempt for %s" % creds['email'] )

    if !creds['email'] or !creds['password']
      Ramaze::Log.info("Login failure : no credentials")
      return false
    end

    user = self[:email => creds['email']]

    if user.nil? 
      Ramaze::Log.info("Login failure : wrong password")
      return false
    end

    # This uses the #password method above
    # and Bcrypt::Password#== method for comparison
    if user.password == creds['password']
      Ramaze::Log.info("Login success")
      return user
    end
  end
end

This should do the trick. The BCrypt documentation for the ruby gem is really nice and very easy to follow, even for non crypto nerds, and gives more options (especially regarding computing cost adjustment).

Clone this wiki locally