views:

91

answers:

2

This question is about a specific programming problem I am having - I want to make sure that my code (and software algorithm) are sufficient enough to store user credentials in a database.

// Get a 32 character salt like '69Mt6nexL1rsjWnu011S53MpB/WmT4Vl'
$passwordSalt = Security::generateBase64Salt();

$user = new User();
$user->setUsername($_POST['username']);

// $_POST['password'] comes in as a 128 character string
// Client side javascript is used to sha512 the string before sending it over POST
// see http://pajhome.org.uk/crypt/md5/
// This prevents novice eavesdroppers from capturing the raw password in plaintext
$user->setPassword(
    hash('sha512', $passwordSalt.$_POST['password'])
);
$user->setPasswordSalt($passwordSalt);
$user->save();

Here's the database entry for a particular password:

alt text

Password:

69a78a7586a111b8a567b2d4f42f93f01fb59d337f7fa3c35949a66b246095778c1fa01ff4026abace476091e1e9a183bbdec1c31b12ce3f786921895c98cf6f

Salt:

69Mt6nexL1rsjWnu011S53MpB/WmT4Vl

Questions:

  • Are there any inherit flaws with this algorithm?
  • Is it OK to store the salt in the same database and table as the salt+password hash?
  • Will having a large 128 character password cause login performance issues (on a magnitude of several seconds) if I have several hundred thousand users in the table?
  • Can this data be reversed to produce the original password?

For Fun:

I'll PayPal you $5 if you can provide me with the original password using the salt and salt + password hash.

+3  A: 

Are there any inherit flaws with this algorithm?

It's not open to rainbow attacks (due to the random salt). Sha512 is a fairly new algorithm, but currently has no known collisions, so it's probably pretty safe. The way your storing passwords is done well. The checking process is also important (rate limiting bruteforce attacks) and locking down the servers from attacks from other angles which could try to get access to the database. If an attacker was able to gain access to the database, he could probably extract out simple passwords fairly quickly, but any complex password would probably beyond a simple bruteforce attack (even if he had direct access to the hashes).

Is it OK to store the salt in the same database and table as the salt+password hash?

You pretty much have to store them together if you want to be able to validate the passwords (I assume you want to). The main reason for salting a password is to remove the possibility of a rainbow attack. Often this data is even stored in the same column as the hashed password using a symbol to separate them.

Will having a large 128 character password cause login performance issues (on a magnitude of several seconds) if I have several hundred thousand users in the table?

Benchmark how long (in seconds) it takes to check a password (hash('sha512', $salt.$password_attempt )). Find the inverse of that number, and that's probably close to how many password attempts you can handle per second per CPU core.

Can this data be reversed to produce the original password?

Yes, but it would take alot of effort, since your using a random salt, rainbow tables will no longer work, and sha512 takes a fair amount of CPU to run and has no known collisions. If the password was fairly simple it could be guessed. If your worried about reversing the hashes, putting a low bound on the complexity of the password might be a good idea (checking it against a dictionary, does it contain upper/lower/numbers/symbols).

Kendall Hopkins
Why the down vote?
Kendall Hopkins
+5  A: 

Everything Kendall said, and ..

.. Skip the hashing that you perform client side in javascript. Instead, just buy a SSL certificate and post the credentials over https. Will protect you from novice eavesdroppers as well as seasoned attackers.

And besides, once you hash on the client side, that effectively becomes your password. If an eavesdropper gets hold off the hashed password, he can pass it to your server and things would just work.

sri
One reason to hash on the client side is to remove the possibility that the password is going to be intercepted (for those users who all use the same password). There are ways to MITM attack SSL, so it's not 100% fool proof. All that said, I think your right on your call to skip that step, as that's such a small part of the problem.
Kendall Hopkins
Hashing passwords client side will not solve MITM attacks, because the hashed password *becomes* the password. SSL is not 100% fool proof, but on that scale encrypting in JS is perhaps 25% foolproof.
sri
I didn't say it would solve the problem. It just removes part of the usefulness of the MITM attack. Since by pre-hashing the password, it's only useful on one site, instead of all the other user's account (because many users use the same password over and over).
Kendall Hopkins