Skip to content

Commit

Permalink
Ensure bcrypt works and move salt generation to encryptors (needed fo…
Browse files Browse the repository at this point in the history
…r bcrypt).
  • Loading branch information
josevalim committed Jan 8, 2010
1 parent d00c313 commit 35838b0
Show file tree
Hide file tree
Showing 11 changed files with 46 additions and 61 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.rdoc
@@ -1,3 +1,11 @@
* enhancements
* Move salt to encryptors

* bug fix
* Bcrypt generator was not being loaded neither setting the proper salt

== 0.8.0

* enhancements
* Warden 0.8.0 compatibility
* Add an easy for map.connect "sign_in", :controller => "sessions", :action => "new" to work
Expand Down
6 changes: 4 additions & 2 deletions lib/devise.rb
Expand Up @@ -11,12 +11,13 @@ module Controllers
end

module Encryptors
autoload :Base, 'devise/encryptors/base'
autoload :Bcrypt, 'devise/encryptors/bcrypt'
autoload :AuthlogicSha512, 'devise/encryptors/authlogic_sha512'
autoload :AuthlogicSha1, 'devise/encryptors/authlogic_sha1'
autoload :RestfulAuthenticationSha1, 'devise/encryptors/restful_authentication_sha1'
autoload :Sha512, 'devise/encryptors/sha512'
autoload :Sha1, 'devise/encryptors/sha1'
autoload :BCrypt, 'devise/encryptors/bcrypt'
end

module Orm
Expand Down Expand Up @@ -48,7 +49,8 @@ module Orm
:sha512 => 128,
:clearance_sha1 => 40,
:restful_authentication_sha1 => 40,
:authlogic_sha512 => 128
:authlogic_sha512 => 128,
:bcrypt => 60
}

# Email regex used to validate email formats. Retrieved from authlogic.
Expand Down
9 changes: 1 addition & 8 deletions lib/devise/encryptors/authlogic_sha512.rb
@@ -1,19 +1,12 @@
require "digest/sha2"

module Devise
# Implements a way of adding different encryptions.
# The class should implement a self.digest method that taks the following params:
# - password
# - stretches: the number of times the encryption will be applied
# - salt: the password salt as defined by devise
# - pepper: Devise config option
#
module Encryptors
# = AuthlogicSha512
# Simulates Authlogic's default encryption mechanism.
# Warning: it uses Devise's stretches configuration to port Authlogic's one. Should be set to 20 in the initializer to silumate
# the default behavior.
class AuthlogicSha512
class AuthlogicSha512 < Base

# Gererates a default password digest based on salt, pepper and the
# incoming password.
Expand Down
20 changes: 20 additions & 0 deletions lib/devise/encryptors/base.rb
@@ -0,0 +1,20 @@
module Devise
# Implements a way of adding different encryptions.
# The class should implement a self.digest method that taks the following params:
# - password
# - stretches: the number of times the encryption will be applied
# - salt: the password salt as defined by devise
# - pepper: Devise config option
#
module Encryptors
class Base
def self.digest
raise NotImplemented
end

def self.salt
Devise.friendly_token
end
end
end
end
15 changes: 6 additions & 9 deletions lib/devise/encryptors/bcrypt.rb
@@ -1,22 +1,19 @@
require "bcrypt"

module Devise
# Implements a way of adding different encryptions.
# The class should implement a self.digest method that taks the following params:
# - password
# - stretches: the number of times the encryption will be applied
# - salt: the password salt as defined by devise
# - pepper: Devise config option
#
module Encryptors
# = BCrypt
# Uses the BCrypt hash algorithm to encrypt passwords.
class BCrypt
class Bcrypt < Base

# Gererates a default password digest based on stretches, salt, pepper and the
# incoming password. We don't strech it ourselves since BCrypt does so internally.
def self.digest(password, stretches, salt, pepper)
::BCrypt::Engine.hash_secret(password, [salt, pepper].flatten.join('xx'), stretches)
::BCrypt::Engine.hash_secret([password, pepper].join, salt, stretches)
end

def self.salt
::BCrypt::Engine.generate_salt
end

end
Expand Down
9 changes: 1 addition & 8 deletions lib/devise/encryptors/clearance_sha1.rb
@@ -1,19 +1,12 @@
require "digest/sha1"

module Devise
# Implements a way of adding different encryptions.
# The class should implement a self.digest method that taks the following params:
# - password
# - stretches: the number of times the encryption will be applied
# - salt: the password salt as defined by devise
# - pepper: Devise config option
#
module Encryptors
# = ClearanceSha1
# Simulates Clearance's default encryption mechanism.
# Warning: it uses Devise's pepper to port the concept of REST_AUTH_SITE_KEY
# Warning: it uses Devise's stretches configuration to port the concept of REST_AUTH_DIGEST_STRETCHES
class ClearanceSha1
class ClearanceSha1 < Base

# Gererates a default password digest based on salt, pepper and the
# incoming password.
Expand Down
9 changes: 1 addition & 8 deletions lib/devise/encryptors/restful_authentication_sha1.rb
@@ -1,20 +1,13 @@
require "digest/sha1"

module Devise
# Implements a way of adding different encryptions.
# The class should implement a self.digest method that taks the following params:
# - password
# - stretches: the number of times the encryption will be applied
# - salt: the password salt as defined by devise
# - pepper: Devise config option
#
module Encryptors
# = RestfulAuthenticationSha1
# Simulates Restful Authentication's default encryption mechanism.
# Warning: it uses Devise's pepper to port the concept of REST_AUTH_SITE_KEY
# Warning: it uses Devise's stretches configuration to port the concept of REST_AUTH_DIGEST_STRETCHES. Should be set to 10 in
# the initializer to silumate the default behavior.
class RestfulAuthenticationSha1
class RestfulAuthenticationSha1 < Base

# Gererates a default password digest based on salt, pepper and the
# incoming password.
Expand Down
9 changes: 1 addition & 8 deletions lib/devise/encryptors/sha1.rb
@@ -1,17 +1,10 @@
require "digest/sha1"

module Devise
# Implements a way of adding different encryptions.
# The class should implement a self.digest method that taks the following params:
# - password
# - stretches: the number of times the encryption will be applied
# - salt: the password salt as defined by devise
# - pepper: Devise config option
#
module Encryptors
# = Sha1
# Uses the Sha1 hash algorithm to encrypt passwords.
class Sha1
class Sha1 < Base

# Gererates a default password digest based on stretches, salt, pepper and the
# incoming password.
Expand Down
9 changes: 1 addition & 8 deletions lib/devise/encryptors/sha512.rb
@@ -1,17 +1,10 @@
require "digest/sha2"

module Devise
# Implements a way of adding different encryptions.
# The class should implement a self.digest method that taks the following params:
# - password
# - stretches: the number of times the encryption will be applied
# - salt: the password salt as defined by devise
# - pepper: Devise config option
#
module Encryptors
# = Sha512
# Uses the Sha512 hash algorithm to encrypt passwords.
class Sha512
class Sha512 < Base

# Gererates a default password digest based on salt, pepper and the
# incoming password.
Expand Down
2 changes: 1 addition & 1 deletion lib/devise/models/authenticatable.rb
Expand Up @@ -43,7 +43,7 @@ def password=(new_password)
@password = new_password

if @password.present?
self.password_salt = Devise.friendly_token
self.password_salt = self.class.encryptor_class.salt
self.encrypted_password = password_digest(@password)
end
end
Expand Down
11 changes: 2 additions & 9 deletions test/encryptors_test.rb
Expand Up @@ -18,18 +18,11 @@ class Encryptors < ActiveSupport::TestCase
assert_equal clearance, encryptor
end

test 'should match a password created by bcrypt' do
bcrypt = "$2a$10$81UWRL4S01M6zxjMPyBame1He8EHYgdFm26rQh0qKzglf2ijtEyfa"
encryptor = Devise::Encryptors::BCrypt.digest('123mudar', 4, '$2a$10$81UWRL4S01M6zxjMPyBame', '')
assert_equal bcrypt, encryptor
end



Devise::ENCRYPTORS_LENGTH.each do |key, value|
test "should have length #{value} for #{key.inspect}" do
swap Devise, :encryptor => key do
assert_equal value, Devise::Encryptors.const_get(key.to_s.classify).digest('a', 2, 'b', 'c').size
encryptor = Devise::Encryptors.const_get(key.to_s.classify)
assert_equal value, encryptor.digest('a', 4, encryptor.salt, nil).size
end
end
end
Expand Down

0 comments on commit 35838b0

Please sign in to comment.