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:
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 s开发者_如何学JAVAalt+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.
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.
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).
精彩评论