Browse files

Change default crypto provider to SCrypt

It is well known that hashes, even when salted, are weak against offline
attacks. Since adaptive hash functions are already supported, default to
the best option so that users start off with the most secure choice by
default.

Signed-off-by: Aaron Bedra <abedra@cigital.com>
  • Loading branch information...
1 parent abc0997 commit 083a95ca59c2610b3071f0ff70c3cb3666e17e86 Aaron Bedra committed Feb 21, 2014
View
2 lib/authlogic/acts_as_authentic/password.rb
@@ -149,7 +149,7 @@ def merge_validates_length_of_password_confirmation_field_options(options = {})
# * <tt>Default:</tt> CryptoProviders::Sha512
# * <tt>Accepts:</tt> Class
def crypto_provider(value = nil)
- rw_config(:crypto_provider, value, CryptoProviders::Sha512)
+ rw_config(:crypto_provider, value, CryptoProviders::SCrypt)
end
alias_method :crypto_provider=, :crypto_provider
View
16 lib/authlogic/crypto_providers/bcrypt.rb
@@ -6,10 +6,14 @@
module Authlogic
module CryptoProviders
- # For most apps Sha512 is plenty secure, but if you are building an app that stores nuclear launch codes you might want to consier BCrypt. This is an extremely
- # secure hashing algorithm, mainly because it is slow. A brute force attack on a BCrypt encrypted password would take much longer than a brute force attack on a
- # password encrypted with a Sha algorithm. Keep in mind you are sacrificing performance by using this, generating a password takes exponentially longer than any
- # of the Sha algorithms. I did some benchmarking to save you some time with your decision:
+ # The family of adaptive hash functions (BCrypt, SCrypt, PBKDF2)
+ # is the best choice for password storage today. They have the
+ # three properties of password hashing that are desirable. They
+ # are one-way, unique, and slow. While a salted SHA or MD5 hash is
+ # one-way and unique, preventing rainbow table attacks, they are
+ # still lightning fast and attacks on the stored passwords are
+ # much more effective. This benchmark demonstrates the effective
+ # slowdown that BCrypt provides:
#
# require "bcrypt"
# require "digest"
@@ -28,7 +32,9 @@ module CryptoProviders
# Sha512: 0.000000 0.000000 0.000000 ( 0.000672)
# Sha1: 0.000000 0.000000 0.000000 ( 0.000454)
#
- # You can play around with the cost to get that perfect balance between performance and security.
+ # You can play around with the cost to get that perfect balance
+ # between performance and security. A default cost of 10 is the
+ # best place to start.
#
# Decided BCrypt is for you? Just install the bcrypt gem:
#
View
13 lib/authlogic/crypto_providers/scrypt.rb
@@ -6,12 +6,13 @@
module Authlogic
module CryptoProviders
- # If you want a stronger hashing algorithm, but would prefer not to use BCrypt, SCrypt is another option.
- # SCrypt is newer and less popular (and so less-tested), but it's designed specifically to avoid a theoretical
- # hardware attack against BCrypt. Just as with BCrypt, you are sacrificing performance relative to SHA2 algorithms,
- # but the increased security may well be worth it. (That performance sacrifice is the exact reason it's much, much
- # harder for an attacker to brute-force your paswords).
- # Decided SCrypt is for you? Just install the bcrypt gem:
+ # SCrypt is the default provider for Authlogic. It is the only
+ # choice in the adaptive hash family that accounts for hardware
+ # based attacks by compensating with memory bound as well as cpu
+ # bound computational constraints. It offers the same guarantees
+ # as BCrypt in the way of one-way, unique and slow.
+ #
+ # Decided SCrypt is for you? Just install the scrypt gem:
#
# gem install scrypt
#
View
6 test/acts_as_authentic_test/logged_in_status_test.rb
@@ -36,9 +36,9 @@ def test_named_scope_logged_out
# test happens so fast that the test fails... I just don't know a better way to test it!
assert User.logged_in.where_values != User.logged_out.where_values, ERROR_MSG % '#logged_out'
- assert_equal 2, User.logged_out.count
+ assert_equal 3, User.logged_out.count
User.first.update_attribute(:last_request_at, Time.now)
- assert_equal 1, User.logged_out.count
+ assert_equal 2, User.logged_out.count
end
def test_logged_in_logged_out
@@ -50,4 +50,4 @@ def test_logged_in_logged_out
assert !u.logged_out?
end
end
-end
+end
View
8 test/acts_as_authentic_test/password_test.rb
@@ -84,7 +84,7 @@ def test_validates_length_of_password_confirmation_field_options_config
end
def test_crypto_provider_config
- assert_equal Authlogic::CryptoProviders::Sha512, User.crypto_provider
+ assert_equal Authlogic::CryptoProviders::SCrypt, User.crypto_provider
assert_equal Authlogic::CryptoProviders::AES256, Employee.crypto_provider
User.crypto_provider = Authlogic::CryptoProviders::BCrypt
@@ -166,10 +166,10 @@ def test_transitioning_password
end
def test_checks_password_against_database
- ben = users(:ben)
+ ben = users(:aaron)
ben.password = "new pass"
assert !ben.valid_password?("new pass")
- assert ben.valid_password?("benrocks")
+ assert ben.valid_password?("aaronrocks")
end
def test_checks_password_against_database_and_always_fails_on_new_records
@@ -233,4 +233,4 @@ def transition_password_to(crypto_provider, records, from_crypto_providers = Aut
end
end
end
-end
+end
View
14 test/fixtures/users.yml
@@ -21,4 +21,16 @@ zack:
single_access_token: <%= Authlogic::Random.friendly_token %>
email: zham@ziggityzack.com
first_name: Zack
- last_name: Ham
+ last_name: Ham
+
+aaron:
+ company: cigital
+ projects: web_services
+ login: abedra
+ crypted_password: <%= Authlogic::CryptoProviders::SCrypt.encrypt("aaronrocks") %>
+ persistence_token: 6cde0674657a8a313ce952df979de2830309aa4c11ca65805dd00bfdc65dbcc2f5e36718660a1d2e68c1a08c276d996763985d2f06fd3d076eb7bc4d97b1e317
+ single_access_token: <%= Authlogic::Random.friendly_token %>
+ perishable_token: <%= Authlogic::Random.friendly_token %>
+ email: abedra@cigital.com
+ first_name: Aaron
+ last_name: Bedra

0 comments on commit 083a95c

Please sign in to comment.