0.0
Repository is archived
No commit activity in last 3 years
No release in over 3 years
Super easy password salting and hashing for ActiveRecord (Rails)
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Runtime

 Project Readme

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