27
votes

I've been working on a project for a while now which uses Devise for user authentication. Whenever a user was created, it would generate a password salt for them along with their encrypted password.

As I'm coming to the tail end of this project, I was testing user registration and noticed that my new roles were not creating a password salt in the database for these new users, whereas my older users all had salts. The new users can sign in fine, yet I'm concerned why Devise is no longer creating salts.

The only oddity with Devise I encountered had to do when I upgraded the module and remember the logs saying something about removing encryptable as bcrypt is now the default encryption, or something to that effect. Which I did so...not sure if this has anything to do with the current issue.

In addition, thinking maybe it was my project that was pooched, I created a brand new Rails application from scratch and added Devise to it, and even that new project isn't creating salts for users.

Is there a new way in Devise to set up password salts, or does anyone know why the salts aren't being created anymore? Unfortunately the Devise wiki doesn't have a whole lot to say on the subject, and Google has been a fruitless search so far.

Or...is it even necessary to have salts in the first place? Seems more secure to have them, I would think.

My config of users/devise is below.

config/initializers/devise.rb

Devise.setup do |config|

  config.mailer_sender = "[email protected]"

  require 'devise/orm/active_record'

  config.authentication_keys = [ :login ]

  config.stretches = 10

  config.encryptor = :bcrypt

  # Setup a pepper to generate the encrypted password.
  config.pepper = "79c2bf3b[...]"

end

app/models/user.rb

  devise :database_authenticatable, :registerable, :confirmable,
         :recoverable, :rememberable, :trackable, :validatable

UPDATE

I was able to locate the notice from after Devise was upgraded, which reads...

[DEVISE] From version 1.2, there is no need to set your encryptor to bcrypt since encryptors are only enabled if you include :encryptable in your models. To update your app, please:

1) Remove config.encryptor from your initializer;
2) Add t.encryptable to your old migrations;
3) [Optional] Remove password_salt in a new recent migration. Bcrypt does not require it anymore.

So it appears that the password_salt is deprecated if you stick with bcrypt, which explains why it's not created anymore. So that answers that, but the other part of my question still remains...is this a good enough practice or should I go with another encryption besides bcrypt?

2
A little update on this topic: I was looking into more information on this topic and apparently BCrypt encrypts the salt into the password, rather than being a separate thing. That would certainly explain why the salt column was dropped in Devise.Shannon

2 Answers

35
votes

The new version of devise uses characters 0 to 29 of the encrypted password field as the salt and the remaining characters in that database field for the encrypted password. So your passwords are actually still salted with BCrypt.

15
votes

Per José Valim:

Devise 1.2.1 does not require a password_salt column anymore if you are using bcrypt. If you need a kind of salt, I believe there is a method called authentication_salt you could use to retrieve such values. (Source)