has_secure_password hashes always unique

I'm using the has_secure_password function in my Rails 3.1 model. I need to verify that the passwords are unique. The has_secure_password function stores the password in a bcrypt hash. It appears the hashes are created with a salt unique to the record, therefore the hash is unique even for the same password. Does anyone know a way around this?

As an example. If I create two users with the username "user" and the password "password", the saved password_digest for each will be different. Because I don't store the password itself, I can't check to be sure the passwords are unique.

billv wrote in post #1018052:

I'm using the has_secure_password function in my Rails 3.1 model. I need to verify that the passwords are unique. The has_secure_password function stores the password in a bcrypt hash. It appears the hashes are created with a salt unique to the record, therefore the hash is unique even for the same password. Does anyone know a way around this?

As an example. If I create two users with the username "user" and the password "password", the saved password_digest for each will be different. Because I don't store the password itself, I can't check to be sure the passwords are unique.

So you are proposing to significantly reduce security of your passwords in order to ensure that two users don't happen to use the same password? Sounds counterproductive to me.

Do you understand the reason, and security advantage, of salted hashes?

What you need to worry about is making sure your users use strong passwords, not whether two users use the same one.

Bottom line is that a lot of thought, by some really smart people, came up with the techniques used for securing computer systems. If you try to outthink them, chances are likely that you'll end up lessening the security of your system not strengthening it.

Why do you care? Why would you allow two users with the same name? And what would you do when someone tries to create the second account with the username "user" and the same password? Give them an error message that explains "sorry you can't do that because there's already a user registered with that name & password"??? Oops :wink:

Oh, I understand the security implications. This is the result of a UI design decision. I won't waste space here with the why's of the matter. Suffice it to say a single username (email) will have multiple passwords. Each password will identify a separate account for that same username (email). Obviously, we should enable a single user to access multiple accounts, but we're not ready to do that right now.

I also do not mean to suggest the salt should go away. I mostly want to control what it is. If I can use the same salt for each of the username passwords, the hashes will match and then I can validate to be sure that they don't.

It's a bit twisted that my reason for wanting the hashes to be the same is so I can force them to be different, but there it is.

Well then, when you create a user, search for a pre-existing user and use its salt if there is one, otherwise let a new salt be generated. Of course you have to watch out for the race condition of two users trying to create the same username at the same time. Either that doesn't happen in your usage scenario (admin setting up all users perhaps), or you have to block it--a simple unique index on username + salt, with retry on constraint failure, would seem to do it.

I don't know where to hook into has_secure_password to do this, but it occurs to me that if you provide a salt yourself before calling it, that should work shouldn't it?

Exactly. Boiling it down, that's what I'm asking. Where is the hook?

Thanks.

I solved the problem with this code: class User < ActiveRecord::Base

  has_secure_password   validate :password_unique?

  protected

  def password_unique?     users = User.find_all_by_email(email)     if users.any?       users.each do |u|         errors.add(:password, "Must be unique within email scope") if u.authenticate(password)       end     end   end

end

Thanks for the responses.

your ui descision seems strange - not only do i have to remembery password - but a different password is going to give me different access???

How do i reset my password???

your ui descision seems strange - not only do i have to remembery password - but a different password is going to give me different access???

How do i reset my password???

The OP is not using the password as a password but as an extension of the user name, to allow a single user to have separate 'accounts' via separate passwords. Why he does not just add an account number and keep the password as a password is unknown.

Colin