= bcrypt-ruby
An easy way to keep your users' passwords secure.
== Why you should use bcrypt
If you store user passwords in the clear, then an attacker who steals a copy of your database has a giant list of emails and passwords. Some of your users will only have one password -- for their email account, for their banking account, for your application. A simple hack could escalate into massive identity theft.
It's your responsibility as a web developer to make your web application secure -- blaming your users for not being security experts is not a professional response to risk.
bcrypt allows you to easily harden your application against these kinds of attacks.
== How to install bcrypt
sudo gem install bcrypt-ruby
You'll need a working compiler. (Win32 folks should use Cygwin or um, something else.)
== How to use bcrypt in your Rails application
=== The +User+ model
require 'bcrypt'
class User < ActiveRecord::Base
users.password_hash in the database is a :string
include BCrypt
def password
@password ||= Password.new(password_hash)
end
def password=(new_password)
@password = Password.create(new_password)
self.password_hash = @password
end
end
=== Creating an account
def create @user = User.new(params[:user]) @user.password = params[:password] @user.save! end
=== Authenticating a user
def login @user = User.find_by_email(params[:email]) if @user.password == params[:password] give_token else redirect_to home_url end end
=== If a user forgets their password?
assign them a random one and mail it to them, asking them to change it
def forgot_password @user = User.find_by_email(params[:email]) random_password = Array.new(10).map { (65 + rand(58)).chr }.join @user.password = random_password @user.save! Mailer.create_and_deliver_password_change(@user, random_password) end
== How to use bcrypt-ruby in general
require 'bcrypt'
my_password = BCrypt::Password.create("my password") #=> "$2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa"
my_password.version #=> "2a" my_password.cost #=> 10 my_password == "my password" #=> true my_password == "not my password" #=> false
my_password = BCrypt::Password.new("$2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa") my_password == "my password" #=> true my_password == "not my password" #=> false
Check the rdocs for more details -- BCrypt, BCrypt::Password.
== How bcrypt() works
bcrypt() is a hashing algorithm designed by Niels Provos and David Mazières of the OpenBSD Project.
=== Background
Hash algorithms take a chunk of data (e.g., your user's password) and create a "digital fingerprint," or hash, of it. Because this process is not reversible, there's no way to go from the hash back to the password.
In other words:
hash(p) #=>
You can store the hash and check it against a hash made of a potentially valid password: