Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bcrypt hash both email address and password

I'm setting up an anonymous site. So basically a user's account cannot be traced back to any actual person (such as by an email address). Authentication is the part that I'd like your thoughts on. If I use the email/pass combo to authenticate can I use bcrypt to hash both the email address and password (well I know this is possible but is it practical)? I thought if the email is encrypted then it'll be extremely slow to search the db to find a match. Is this true/false? What are your thoughts? Any other ideas? Basically, I'm open to any ideas on how to authenticate, but if it's authenticated with an email then it can't be exposed/or decrypt-able. Thanks!

like image 486
Jeffrey Avatar asked Jan 24 '26 22:01

Jeffrey


2 Answers

Once you hash something, the original can never be recovered.

Let's take a password for instance, typically when a user signs up with an email/password you'll hash the password (with something like bcrypt), then store the hash in your database. This is great because if an attacker gets a copy of the database, there's no way to 'decrypt' the hash.

In your situation, you probably WON'T want to hash the email because that means you'll never be able to email the person -- which I'm assuming you'll want to do.

If you decide to go that route, you'll basically just be storing two passwords per user (that's the closest analogy I could come up with, sorry!).

Hope that helps!

EDIT: A better way to do this would be to create a new account given ONLY a password -- and then you generate a username for the person automatically. This is what companies like privateinternetaccess.com do -- they'll generate some random username for you -- this way you can't contact the user, but they can still safely log into your application.

like image 117
rdegges Avatar answered Jan 28 '26 12:01

rdegges


i don't see any problem with your idea (assuming that you never want to asynchronously send email to the user).

login:

  1. user posts a login form that has cleartext email and cleartext password (of course you use good TLS transport encryption)
  2. eh = h(email), ph = h(password)
  3. fetch the record from user database where eh == stored_eh
  4. compare ph against stored_ph

forgot password procedure: in the very moment the user posts the "forgot password" form with his cleartext email address, you HAVE his email. compute eh, lookup profile, generate onetime token, store it into profile and put it into a mail to his email address. he can then use the token to define a new password.

change email procedure: similar to above, you have the cleartext old/new email addrs in the moment the form is posted.

Notes:

  • the db lookup in step 3 is not slower than using a plaintext search key
  • for 2 and 4, use some sane code from a well-maintained library (scrypt, bcrypt, pbkdf2, sha512_crypt, not just a simple salted-hash)
  • if an attacker gets your database and has a list of potential email addrs, he can easily find out whether you have (some of) them as users and determine their user record in your db. if that is a problem, you maybe could use h(email+password), but then there is no password recovery possible.
like image 41
Thomas Waldmann Avatar answered Jan 28 '26 10:01

Thomas Waldmann



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!