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