Salt and Pepper
Provides automatic password hashing for ActiveRecord (>= 3.0.4) and a couple of methods for generating random strings, tokens, etc.
Features:
- Mark columns for auto-hashing with a single line of code.
- Automatic salting of hashes. No separate column is required for the salt.
- Does not break validations on the hashed columns (only a small change is required).
- Super easy hash verification.
- Tested using RSpec 2
Digest::SHA256
is used for hashing and ActiveSupport::SecureRandom
is used for generating random stuff.
Installation
Just add it to your Gemfile and run bundle install
:
gem "salt-and-pepper"
Note: Rails 3.0.4 or higher is required.
Usage
To enable automatic hashing for a column, call hash_column
in your model:
class User < ActiveRecord::Base hash_column :password end
You can specify multiple columns in one line or in separate lines:
class User < ActiveRecord::Base hash_column :password, :security_token # or hash_column :password hash_column :security_token end
Options
You can pass the :length
option to change the length of the stored hash.
Numbers between 96 and 192 are accepted, the default value is 128. Make sure the database column can store a string that long!
# set length for both columns hash_column :password, :security_token, :length => 100 # or adjust them individually hash_column :password, :length => 160 hash_column :secret, :length => 120
By default, blank (= empty or whitespace-only) strings will be converted to nil
, and will not be hashed.
If you really want blank strings to be hashed, use the :hash_blank_strings
option:
# Default behavior: # nil => nil # empty string => nil # whitespace-only string => nil hash_column :password, :hash_blank_strings => true # New behavior: # nil => nil # empty string => 77c0a93ad8e5f42cf676... # whitespace-only string => 1b8d091174299844b1a4...
Verification
Just compare the two values:
if @user.password == "secret" # password is valid end
A full example:
# app/models/user.rb class User < ActiveRecord::Base hash_column :password end # app/controllers/sessions_controller.rb def create @user = User.find_by_username(params[:username]) if @user.present? && @user.password == params[:password] # login user here else redirect_to new_session_path, :alert => "Invalid username or password." end end
Validating hashed columns
Salt and Pepper provides the validate_[column]?
method for deciding whether validations on the column should be performed.
Use it to prevent running your sophisticated length-checking algorithms on a 128-character hash :). Skipping validation of hashed values is safe because they were already checked at the time they were set.
class User < ActiveRecord::Base encrypt :password validates :password, :length => { :within => 6..100 }, :if => :validate_password? end
Generating random stuff
Salt and Pepper has a couple of handy methods for generating random numbers, codes, tokens, etc:
SaltPepper.number(6) # => 4 (identical to: 0..5) SaltPepper.number(10..20) # => 11 SaltPepper.alpha_code # => "SNPBJSDG" SaltPepper.alpha_code(4) # => "FKNP" SaltPepper.numeric_code # => "01570475" SaltPepper.numeric_code(20) # => "70110124996934848762" SaltPepper.code # => "29Y3WSEC" (alphanumeric) SaltPepper.code(5) # => "89U1F" SaltPepper.code(10, 'a'..'z') # => "mqxeozlelw" SaltPepper.code(15, (0..1).to_a + ('a'..'b').to_a) # => "0ab1b0b1b01a0a1" SaltPepper.token # => "a0d5828f79e9e22dbc1f896e49f8183a" SaltPepper.token(16) # => "caa4a085edb19499"
License
Released under the MIT license.
Copyright © Máté Solymosi 2011