Lowering BCrypt cost with has_secure_password

Nov 29, 2012

rails

One of the strengths of an algorithm like
BCrypt for storing encrypted
passwords lies in the fact that it is relatively slow and can readily be
made slower. This makes brute force attacks time-prohibitive. The
bcrypt-ruby gem gives you easy
access to this cost factor to slow down encryption as needed. The
default cost is 10. This provides good security for encrypting user
passwords, but if your Rails application depends on users being signed
in, you may find this default cost has a substantial impact on the
performance of your integration tests. Both
Devise and
Authlogic provide hooks into
their BCrypt interface which allows you to easily change the cost, and
this can come in very handy during testing.

# Place in test_helper.rb or spec_helper.rbDevise.setupdo|config|config.stretches=1end

# Place in test_helper.rb or spec_helper.rbAuthLogic::CryptoProviders::BCrypt.cost=1

If you’re authentication needs are simple and you have instead opted to
use Rails’
SecurePassword,
you will find that, at least as of Rails 3.2.9, there is no obvious way
to lower the cost factor. However, if you’re willing to live with a
little monkey patching, you can achieve the same results.

# Place in test_helper.rb, spec_helper.rb or spec/support/...require'bcrypt'classBCrypt::Passwordclass<<selfmethod=instance_method(:create)define_method:createdo|arg,options={cost: 1}|method.bind(self).call(arg,options)endendend

Is it worth doing? Here are the before and after measurements on an
application I’m currently working on. This particular application is an
internal application for a client. There are no guest features, which
means every single feature depends on a user having first signed in.