3

I've been doing some research into password hashing implementations and would like to know if it's feasible to have two servers hash passwords to the same database?

I've come across the Bcrypt.net library, which provides 2 methods to hash and verify. What I'm intrigued is what it does in the hashing stage. I was under the impression that the salt had to be random, and with this library the salt is stored in the same string as the hashed password. However, I've tried hashing on my desktop, then verifying on another machine, and it appears to check out. So what is happening?

Should I think about using another hashing implementation for this load balancing setup?

Esteri
  • 33
  • 2

1 Answers1

2

This should be fine.

I'm going to split your question into two parts:

1. How does bcrypt work in terms of salt usage & storage?
Salts are used for a number of reasons - mainly to prevent rainbow table attacks and make unique hashes for non-unique passwords.

Rainbow tables are huge dictionaries of hashes and their plaintext. The idea is to look up the hash, and find the associated plaintext. In order to make this difficult, each password is salted with a unique value, ensuring that each password must be cracked separately.

If two users have the same password, with no salt, the hashes will be the same. This opens us up to coincidental attacks. If two users have the same password, but different salts, the hashes will be different.

The thing about salts is that you can store them in plaintext, because they don't need to be any more secret than your strong password hashes. As such, bcrypt simply stores the salt in plaintext within the hash:

$2a$05$TwentyTwoCharsForASalt$e2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi

This is split out into the following tokens:

  • The 2a prefix to identify the hash as a blowfish crypt (i.e. bcrypt)
  • A two-digit work factor (usually limited at 04 to 31)
  • A 22-character salt value, from the values a-z A-Z 0-9 . /
  • The hash value.

As such, the parameters required for verifying the hash (including the salt) are stored within the hash string itself. When the verify function is called, it validates the prefix, extracts the work factor and salt, computes the hash of the given password (using the work factor and salt) and compares the result to the hash stored in the given hash string.

2. Can I do this in a load balancing scenario?
Yes. There are no issues here whatsoever. Just compute the hash on a machine, and insert it into the database. There is no point trying to distribute a single hash operation across multiple machines using cloud voodoo. Just tweak your work factor to fit with your performance and security requirements, and be done with it. If your server(s) can't take it, drop the work factor in your hash creation code. Since it's stored in the hash, new hashes will automatically use the lower value, and old hashes will be unaffected.

If you really really need to do it over multiple servers, set up a work distribution system so that each hash is computed on an available box. However, at that point I'd argue that you've got bigger problems than just hashing passwords.

Concurrency issues in your database system are unrelated to the hash function you're using, so if you're having problems with that I suggest you post a question on Database Administrators.

Polynomial
  • 132,208
  • 43
  • 298
  • 379
  • Thank you. I'm not planning to do the hashing over several servers, I was more worried registration attempts sent to one server THEN sending a login request to another server would result in failed hash verifications. Glad to see this isn't the case. – Esteri Aug 28 '12 at 14:04