Jump to content

How to Safely Store Passwords


doubledee

Recommended Posts

  • Replies 54
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Because hash_hmac() also requires a cryptographic key to compute the hash, and hash() does not.

 

Even if they have a full dump of your database with the hashes, trying to brute force them would be futile without the cryptographic key.

 

Oops!  Can we back up a few steps?  (And don't get all impatient like KevinM1...)

 

I read a bunch last night on related topics, but think today that I am losing site of why I am doing all of this anyways...  :confused:

 

 

Questions:

 

1.) What exactly is the purpose of a "Rainbow Table"?

 

It is just a cross-reference between potential Readable Passwords and Hashed Passwords, right?

 

 

2.) How does having a "Rainbow Table" really help a hacker?

 

The hacker still has to make a million guesses as to what my Username and Password are, right?

 

 

3.) How does having a Salt make it even harder still for a hacker to break in?

 

 

4.) I thought all good systems locked out users after like 3 failed attempts?

 

So how do "Brute Force" attacks work?

 

 

5.) Is all of this stuff we have been discussing designed to protect my Website or my Database?

 

 

6.) Since I am not storing credit cards, how exacting do I need to be?

 

I spent a few hours reading things last night, including this interesting article...

 

http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html

 

Bottom line:  Everyone claims the "other guy" is wrong, which leaves me wondering if anything is "secure"?!

 

I really, really want to be *secure*, but this is a more complicated topic than most people give it credit for, AND since I do not have a Ph.D. from Standford and a $1 million, I need to be practical in coming up with solutions!!

 

Thanks,

 

 

Debbie

 

 

Link to comment
Share on other sites

Questions:

 

1.) What exactly is the purpose of a "Rainbow Table"?

 

It is just a cross-reference between potential Readable Passwords and Hashed Passwords, right?

 

It is a reference between hash values and known plaintext values that will produce that hash. It may not necessarily be the original plaintext value, as it is possible for more than one plaintext value to produce the same hash value. This is called a collision, and is much more likely to happen with the smaller hashes such as MD5 and SHA1.

 

2.) How does having a "Rainbow Table" really help a hacker?

 

A rainbow table is only useful when the malicious user has obtained the raw hashes and other data from your database table.

 

The hacker still has to make a million guesses as to what my Username and Password are, right?

 

That has nothing to do with a rainbow table. That's a dictionary attack. I cavered that in my post above.

 

3.) How does having a Salt make it even harder still for a hacker to break in?

 

It doesn't make it any harder to break in. It makes it immensely more difficult to use the values obtained from your database in the event the database is compromised.

 

4.) I thought all good systems locked out users after like 3 failed attempts?

 

Locking out accounts after a certain number of failed attempts is a good idea, yes. Logging every time that happens is also a good idea.

 

So how do "Brute Force" attacks work?

 

See my post in reply #17

 

5.) Is all of this stuff we have been discussing designed to protect my Website or my Database?

 

Yes.

 

6.) Since I am not storing credit cards, how exacting do I need to be?

 

Since people tend to use the same password on multiple sites, including sites such as their bank, keeping the username/password pairs protected is somewhat more than a mere triviality.

 

I spent a few hours reading things last night, including this interesting article...

 

http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html

 

Bottom line:  Everyone claims the "other guy" is wrong, which leaves me wondering if anything is "secure"?!

 

Where did that happen?

 

I really, really want to be *secure*, but this is a more complicated topic than most people give it credit for, AND since I do not have a Ph.D. from Standford and a $1 million, I need to be practical in coming up with solutions!!

 

Thanks,

 

 

Debbie

 

 

Link to comment
Share on other sites

Myself, it really depends on the script itself.

Sometimes I leave plain text passwords

Sometimes I use md5/sha1 + salt

 

The deciding factor on which system to use, is script security. If you sanitize/validate external data, and are relatively sure that the script is secure from hack attempts.

If there is 1 or 2 admin users, you should be relatively ok with plain text passwords (of course this is on a dedicated server with few ppl who have access)

 

People can bring up the brute force argument, but listen, if you allow an infinite amount of logins, than you have a big security hole in the first place.

only allow a certain number of password attempts before locking out the account, sending email/notices to staff.

 

You don't need to get all crazy with the hash system. A random salt added to the users record, and updated every so often is a good idea.

but there is no need for 1000 char salts, or repeating the hash generation.

 

Security is reliant on Staff/users and coding to handle external data. Poor judgement in either will usually compromise your data.

 

 

Link to comment
Share on other sites

Questions:

 

1.) What exactly is the purpose of a "Rainbow Table"?

 

It is just a cross-reference between potential Readable Passwords and Hashed Passwords, right?

 

It is a reference between hash values and known plaintext values that will produce that hash. It may not necessarily be the original plaintext value, as it is possible for more than one plaintext value to produce the same hash value. This is called a collision, and is much more likely to happen with the smaller hashes such as MD5 and SHA1.

 

Okay.

 

 

2.) How does having a "Rainbow Table" really help a hacker?

 

A rainbow table is only useful when the malicious user has obtained the raw hashes and other data from your database table.

 

So Rainbow Tables help after a Data Breach has occurred?

 

 

The hacker still has to make a million guesses as to what my Username and Password are, right?

 

That has nothing to do with a rainbow table. That's a dictionary attack. I cavered that in my post above.

 

If you lock people out after 3 failed attempts, that solves that issue 100% of the time, right??

 

 

3.) How does having a Salt make it even harder still for a hacker to break in?

 

It doesn't make it any harder to break in. It makes it immensely more difficult to use the values obtained from your database in the event the database is compromised.

 

How crazy do I have to get with Salting?

 

What was the difference again between scootstah's approach and DarkFreaks seemingly involved code?

 

 

So how do "Brute Force" attacks work?

 

See my post in reply #17

 

As I said above, it seems like Brute Force Attacks can be completely eliminated??

 

 

I spent a few hours reading things last night, including this interesting article...

 

http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html

 

Bottom line:  Everyone claims the "other guy" is wrong, which leaves me wondering if anything is "secure"?!

 

Where did that happen?

 

I don't follow you?!

 

I was saying that everyone seems to have widely varying approaches and opinions on even the simplest things like making Passwords secure in your database, and so it seems like they cancel each other out?!

 

For instance, how would a mere mortal like me know whether DarkFreaks or scootstah approach is better?

 

 

Debbie

 

Link to comment
Share on other sites

Myself, it really depends on the script itself.

Sometimes I leave plain text passwords

Sometimes I use md5/sha1 + salt

 

The deciding factor on which system to use, is script security. If you sanitize/validate external data, and are relatively sure that the script is secure from hack attempts.

If there is 1 or 2 admin users, you should be relatively ok with plain text passwords (of course this is on a dedicated server with few ppl who have access)

 

People can bring up the brute force argument, but listen, if you allow an infinite amount of logins, than you have a big security hole in the first place.

only allow a certain number of password attempts before locking out the account, sending email/notices to staff.

 

You don't need to get all crazy with the hash system. A random salt added to the users record, and updated every so often is a good idea.

but there is no need for 1000 char salts, or repeating the hash generation.

 

Security is reliant on Staff/users and coding to handle external data. Poor judgement in either will usually compromise your data.

 

 

 

That's great until your database gets hacked and they have free passwords. Just because 1 or 2 people have access doesn't mean you can't be hacked. If Sony and Steam can be, you can be.

 

 

So Rainbow Tables help after a Data Breach has occurred?

 

Yes, the attacker would need to have the password hashes so they must have obtained them from the database in some way. Either finding an SQL injection vulnerability, through a CMS somehow, or by gaining access to the database directly.

 

 

If you lock people out after 3 failed attempts, that solves that issue 100% of the time, right??

 

Well no, but it slows them down at least.

 

 

How crazy do I have to get with Salting?

 

Nothing too crazy. A 10 character long unique random string will work fine.

 

What was the difference again between scootstah's approach and DarkFreaks seemingly involved code?

 

My approach uses a stronger hashing algorithm (sha512 vs sha256) as well as the more secure hash_hmac() (vs hash(), which I already explained the difference between the two). Also, DarkFreak needlessly re-hashes the hash a lot of times, which really does nothing.

 

 

As I said above, it seems like Brute Force Attacks can be completely eliminated??

 

It depends what sort of brute force you are talking about. Do you mean brute force the login from the website, IE: try a bunch of username/password combination until one works? Yeah that can be slowed down by having login attempt restrictions. Note though that use of proxies, cookie clearing, different usernames etc can all bypass such attempts. It is difficult to secure that really well without inconveniencing honest users.

 

If however you mean brute forcing the hashes by means of finding collisions and such, there's nothing you can do to "prevent" that, but you can make it more difficult. They would of course need to have the hashes available so they would have had to already obtain them from the database in some way. Once they do that it's just a matter of time and how much effort they put forth to cracking them. If you use my hash_hmac() approach (which uses the cryptographic key to compute the hash) then they will also need that key in order to brute force the hash.

 

?!

I was saying that everyone seems to have widely varying approaches and opinions on even the simplest things like making Passwords secure in your database, and so it seems like they cancel each other out?!

 

It's true, there's a lot of controversy on the subject. The thing you need to ask yourself is how likely you are to being hacked. If you have a small community website or some small e-store or something like that, chances are you are a very small target. And as such, anyone that does attempt something is probably unlikely to succeed due to lack of motivation and/or resources. Keep in mind that no matter what sort of hashing algorithm you use, unless they gain access to your database you're fine. You could store them as plain text as you want and so long as they never get your database, they can never crack the passwords (except by trying to login until they get it right - which has no bearing on whether or not the password is hashed or salted or whatnot).

 

So put simply, pick something that isn't needlessly complicated (such as my approach) and go with it. Anything more than MD5/SHA1 with properly salted hashes will take a significant amount of time for your average script kiddie to crack. And that's IF they even get them from the database in the first place.

 

It sounds like you are way too concerned about this.

 

For instance, how would a mere mortal like me know whether DarkFreaks or scootstah approach is better?

 

Well like I said, there's a lot of controversy on the subject. There's a million different ways. No offense meant to DarkFreaks, but his approach seems inefficient and unnecessarily complicated. Rehashing 100,000 times is going to exactly nothing in terms of more secure. In fact it may even do the opposite.

 

You can either search for days and weeks until you find something you feel comfortable with, but I think you are just wasting your time. Pick something reasonable and go with it.

 

Link to comment
Share on other sites

So Rainbow Tables help after a Data Breach has occurred?

 

Yes, the attacker would need to have the password hashes so they must have obtained them from the database in some way. Either finding an SQL injection vulnerability, through a CMS somehow, or by gaining access to the database directly.

 

Sorry, it has been a long day and I'm tired...

 

Let me recap some things...

 

- If a hacker gets into your database, then plain-text passwords are dead giveaways, right?

 

- If a hacker gets into your database, then hashed passwords are much harder to decipher, right?

 

Specifically, in theory you can only crack hashed passwords using a Rainbow Table, right?

 

- All of you are saying that I should have a unique Salt for every hashed password, right?

 

- And you are telling me to store the Salt in the database, right?

 

- But if hacking the database is the only real way to compromise passwords, then what is the logic of storing individual Salts in the database that might get hacked?!

 

 

 

How crazy do I have to get with Salting?

 

Nothing too crazy. A 10 character long unique random string will work fine.

 

Why 10 characters?

 

 

My approach uses a stronger hashing algorithm (sha512 vs sha256) as well as the more secure hash_hmac() (vs hash(), which I already explained the difference between the two). Also, DarkFreak needlessly re-hashes the hash a lot of times, which really does nothing.

 

If you use my hash_hmac() approach (which uses the cryptographic key to compute the hash) then they will also need that key in order to brute force the hash.

 

What is a "cryptographic key"?

 

 

?!

I was saying that everyone seems to have widely varying approaches and opinions on even the simplest things like making Passwords secure in your database, and so it seems like they cancel each other out?!

 

It's true, there's a lot of controversy on the subject. The thing you need to ask yourself is how likely you are to being hacked. If you have a small community website or some small e-store or something like that, chances are you are a very small target. And as such, anyone that does attempt something is probably unlikely to succeed due to lack of motivation and/or resources. Keep in mind that no matter what sort of hashing algorithm you use, unless they gain access to your database you're fine. You could store them as plain text as you want and so long as they never get your database, they can never crack the passwords (except by trying to login until they get it right - which has no bearing on whether or not the password is hashed or salted or whatnot).

 

So put simply, pick something that isn't needlessly complicated (such as my approach) and go with it. Anything more than MD5/SHA1 with properly salted hashes will take a significant amount of time for your average script kiddie to crack. And that's IF they even get them from the database in the first place.

 

Okay.

 

 

It sounds like you are way too concerned about this.

 

I am way to concerned about EVERYTHING!!!  8)

 

I don't want to become a statistic of another hacked/poorly coded website...

 

 

 

For instance, how would a mere mortal like me know whether DarkFreaks or scootstah approach is better?

 

Well like I said, there's a lot of controversy on the subject. There's a million different ways. No offense meant to DarkFreaks, but his approach seems inefficient and unnecessarily complicated. Rehashing 100,000 times is going to exactly nothing in terms of more secure. In fact it may even do the opposite.

 

You can either search for days and weeks until you find something you feel comfortable with, but I think you are just wasting your time. Pick something reasonable and go with it.

 

True.

 

 

Debbie

 

 

Link to comment
Share on other sites

Reason I said that the password hash system shouldnt be a big worry on your security list. a simple unique salt hash system should suffice.

The bigger question is external data and users. which you should be looking at closely. This is where a lot of ppl fail miserably.

They spend 2days on a hashing system that doesnt provide any more security than say

$salt=md5(time());{/code] and usually leave gaping holes when handling $_GETS/$_POST information.

Link to comment
Share on other sites

- If a hacker gets into your database, then plain-text passwords are dead giveaways, right?

Yes

 

- If a hacker gets into your database, then hashed passwords are much harder to decipher, right?

 

Specifically, in theory you can only crack hashed passwords using a Rainbow Table, right?

Without a salt, they are only a bit harder to decipher, and would only deter someone not really interested.  The salt makes it much harder as it nullifies any existing rainbow tables.

 

- All of you are saying that I should have a unique Salt for every hashed password, right?

 

- And you are telling me to store the Salt in the database, right?

Yes and yes

 

 

- But if hacking the database is the only real way to compromise passwords, then what is the logic of storing individual Salts in the database that might get hacked?!

 

The salt does not have to be a secret.  The point of the salt is to ensure the hash that is generated is something more unique such that it will not appear in any existing rainbow tables the hacker may have.  They would have to re-generate their table using the salt before searching for the hash to determine what the password might be.  Depending on the speed of the algorithm you use for your hashing this could take them anywhere from hours to several years.  If you use a salt that is unique for each user, then they will also have to re-generate the table on a user-by-user basis rather than just once for your whole DB.

 

 

 

Why 10 characters?

 

No particular reason.  10 is a nice round number.  Even a single character would affect the hash output, 10 just adds more randomness to the equation.  I usually see strings typically between 4 and 10 characters used as salt values.

 

 

What is a "cryptographic key"?

http://en.wikipedia.org/wiki/Key_(cryptography)

 

 

Link to comment
Share on other sites

Specifically, in theory you can only crack hashed passwords using a Rainbow Table, right?

 

No, there are other ways an attacker could potentially recover a password. One way is to cause a collision. Collisions are more common and easy to find the smaller and faster the hash algorithm is. For example, MD5 is pretty easy to find collisions.

 

A collision is basically another value creating the same hash. So an attacker would loop through endless amounts of permutations until something created the same hash. Using a stronger algorithm like sha256 or sha512 is going to significantly decrease the chances of this happening.

 

 

- But if hacking the database is the only real way to compromise passwords, then what is the logic of storing individual Salts in the database that might get hacked?!

 

The one and only role of a salt is to prevent rainbow table attacks. That's it. You would have to create a rainbow table for every user. If you have hundreds of thousands of users, you're talking an extremely high amount of storage for those rainbow tables. Not to mention the time it would take to create them. You would need a very dedicated attacker.

 

 

Why 10 characters?

 

Like kicken said, 10 sounds good. There's no need to go crazy with the salt and store like a 40 character string, you're just taking up unnecessary storage space. 10 (or less) characters will still do its job just fine.

 

 

What is a "cryptographic key"?

 

Basically, it is a static string (usually long and random, say 256 bit or so) that is used to compute the hash. It is just extra entropy that is required to have to reproduce the same hash. So even if an attacker got ahold of your hashes, they would also need the cryptographic key which means you would have to be compromised in two places instead one (database and the filesystem).

 

 

They spend 2days on a hashing system that doesnt provide any more security than say

$salt=md5(time());

 

Sorry, but this is simply not true. The amount of time it takes to break MD5 with modern hardware is laughable. After creating an inefficient looping function in 10 seconds and using a wordlist, I can generate 400,000 MD5 hashes in .5 seconds with 1 thread on my Core i5. Now think about people who actually care and have 4 CUDA cards running in unison. They're going to obliterate MD5.

 

In fact there are websites that exist to search MD5 hashes and get back a plaintext result. Obviously salts would thwart that, but I'm just pointing out how broken MD5 is for anything security related.

Link to comment
Share on other sites

- But if hacking the database is the only real way to compromise passwords, then what is the logic of storing individual Salts in the database that might get hacked?!

 

The salt does not have to be a secret.  The point of the salt is to ensure the hash that is generated is something more unique such that it will not appear in any existing rainbow tables the hacker may have.  They would have to re-generate their table using the salt before searching for the hash to determine what the password might be.

 

Okay, but a few things...

 

1.) If a hacker knows your Salt, then can't they somehow use that to "reverse-engineer" things and easily crack your Salted Hashes?

 

2.) As Rainbow Tables grow and grow, won't it become impossible for any of this to work?

 

Why you can buy up to a 5 TeraByte Rainbow Table here...

http://www.freerainbowtables.com/en/tables2/

 

I would think that Salting is losing its value already?!

 

 

Depending on the speed of the algorithm you use for your hashing this could take them anywhere from hours to several years.

 

If I use the "Kicken Super-Duper Hashing Algorithm" to hash my Plain-Text Passwords, you are saying that using that *specific* algorithm takes ___ amount of time to hash things right?

 

And so if I was a hacker, then I would have to use the same "Kicken Super-Duper Hashing Algorithm" to create my Rainbow Table, right  And so therefore, if it took 1 minute to hash each value, then it would take years to do the whole dictionary or whatever, right?

 

3.) Is there a way to "speed up" or "slow down" hashing algorithms?

 

 

 

Why 10 characters?

 

No particular reason.  10 is a nice round number.  Even a single character would affect the hash output, 10 just adds more randomness to the equation.  I usually see strings typically between 4 and 10 characters used as salt values.

 

If I use SHA512 then that create a Hash that is 128 Characters long, right?  (Meaning I could use a CHAR(128) in MySQL, right?)

 

Doesn't adding a 10 Character Salt onto the Password impact the length of my Hash?

 

And what would happen if I have a "Pass-Phrase" which was longer than the Hash itself (e.g. 500 Characters)?

 

 

Debbie

 

Link to comment
Share on other sites

Specifically, in theory you can only crack hashed passwords using a Rainbow Table, right?

 

No, there are other ways an attacker could potentially recover a password. One way is to cause a collision. Collisions are more common and easy to find the smaller and faster the hash algorithm is. For example, MD5 is pretty easy to find collisions.

 

A collision is basically another value creating the same hash. So an attacker would loop through endless amounts of permutations until something created the same hash. Using a stronger algorithm like sha256 or sha512 is going to significantly decrease the chances of this happening.

 

You lost me...

 

A Rainbow Table is taking a list of potential password (e.g. Dictionary Words, Random Letters, etc) and calculating a Hash for each.  Then when a Hash is obtained throw hacking or a data breach, the Hacker just takes the compromised Hash, and looks it up to see what it is in English (or whatever).

 

Are you saying a Collision is looking for MANY Passwords that create the SAME Hash?

 

If so, how does that help a hacker?

 

Regardless, what you described above sounds more like just creating a Rainbow Table...

 

 

- But if hacking the database is the only real way to compromise passwords, then what is the logic of storing individual Salts in the database that might get hacked?!

 

The one and only role of a salt is to prevent rainbow table attacks. That's it. You would have to create a rainbow table for every user. If you have hundreds of thousands of users, you're talking an extremely high amount of storage for those rainbow tables. Not to mention the time it would take to create them. You would need a very dedicated attacker.

 

Okay, but as I said above in my last response, I was just fearful that displaying the Salt out in the open would allow a hacker to "reverse-engineer" your Hash and crack it quicker?!

 

 

Why 10 characters?

 

Like kicken said, 10 sounds good. There's no need to go crazy with the salt and store like a 40 character string, you're just taking up unnecessary storage space. 10 (or less) characters will still do its job just fine.

 

Okay.

 

 

What is a "cryptographic key"?

 

Basically, it is a static string (usually long and random, say 256 bit or so) that is used to compute the hash. It is just extra entropy that is required to have to reproduce the same hash. So even if an attacker got ahold of your hashes, they would also need the cryptographic key which means you would have to be compromised in two places instead one (database and the filesystem).

 

Hang on...  Is a Cryptographic Key the same thing as a Salt?

 

Earlier you posted this code...

function hash_password($password, $salt = null)
{
if (!is_null($salt))
	$salt = substr(sha1(uniqid(mt_rand(), true)), 0, 10);

// this should be a long, random string
// stored somewhere safe
$key = 'abcdef';

$hash = hash_hmac('sha512', $password, $key);

return array($hash, $salt);
}

 

I see a $key in your hash_hmac function, but where did the $salt go???

 

 

Debbie

 

Link to comment
Share on other sites

1.) If a hacker knows your Salt, then can't they somehow use that to "reverse-engineer" things and easily crack your Salted Hashes?

 

No, you can't reverse-engineer a hash. It is one-way. Simply knowing the salt gives them no advantage at all.

 

2.) As Rainbow Tables grow and grow, won't it become impossible for any of this to work?

 

Why you can buy up to a 5 TeraByte Rainbow Table here...

http://www.freerainbowtables.com/en/tables2/

 

I would think that Salting is losing its value already?!

 

See, you are missing the point. You would need a rainbow table for every user. So therefore if you have 1000 users, you would need 5 petabytes to store all those rainbow tables. A (very fast) Google search puts the current hard drive market at $0.07/GB. So 5 petabytes would cost roughly $360,000 USD. Do you really think someone is going to invest that much money to hack your website?

 

And then add on to the fact that it would take a very long time to compile all of those rainbow tables. Remember that when you use a salt, the rainbow table has to be constructed specifically for that specific salt.

 

 

And so if I was a hacker, then I would have to use the same "Kicken Super-Duper Hashing Algorithm" to create my Rainbow Table, right  And so therefore, if it took 1 minute to hash each value, then it would take years to do the whole dictionary or whatever, right?

 

Yes.

 

3.) Is there a way to "speed up" or "slow down" hashing algorithms?

 

No.

 

 

If I use SHA512 then that create a Hash that is 128 Characters long, right?  (Meaning I could use a CHAR(128) in MySQL, right?)

 

Yes.

 

 

Doesn't adding a 10 Character Salt onto the Password impact the length of my Hash?

 

No, because you don't add the salt to the hash, you add the salt to the password and then hash both. So if your password was "password1" and the salt was "abcdef", you would hash the string "password1abcdef".

 

And what would happen if I have a "Pass-Phrase" which was longer than the Hash itself (e.g. 500 Characters)?

 

It doesn't matter, the length of the hash would remain the same.

Link to comment
Share on other sites

Are you saying a Collision is looking for MANY Passwords that create the SAME Hash?

 

No, a collision is when two separate strings create the same hash. For example let's say the hash of "password1" is "7c6a180b36896a0a8c02787eeafb0e4c". A collision would be another value that also happens to have the hash "7c6a180b36896a0a8c02787eeafb0e4c".

 

 

If so, how does that help a hacker?

 

Because if an attacker can regenerate a hash with another value, they could use that value to login. If the user's password is really "password1", but "blurgablur" creates the same hash then they can use that to login with.

 

 

Okay, but as I said above in my last response, I was just fearful that displaying the Salt out in the open would allow a hacker to "reverse-engineer" your Hash and crack it quicker?!

 

As I said above that is not possible. Hashing is one way and you cannot reverse-engineer it.

 

 

Hang on...  Is a Cryptographic Key the same thing as a Salt?

 

In this context it would be referred to as a "pepper". A salt is unique for each user, whereas a pepper is static. Moreover, they are not stored in the same location (one in the database, one in the filesystem) so both would have to be compromised.

 

Earlier you posted this code...

function hash_password($password, $salt = null)
{
if (!is_null($salt))
	$salt = substr(sha1(uniqid(mt_rand(), true)), 0, 10);

// this should be a long, random string
// stored somewhere safe
$key = 'abcdef';

$hash = hash_hmac('sha512', $password, $key);

return array($hash, $salt);
}

 

I see a $key in your hash_hmac function, but where did the $salt go???

 

My apologies, I forgot to stick the salt in there. It would go here:

$hash = hash_hmac('sha512', $password . $salt, $key);

Link to comment
Share on other sites

2.) As Rainbow Tables grow and grow, won't it become impossible for any of this to work?

 

Why you can buy up to a 5 TeraByte Rainbow Table here...

http://www.freerainbowtables.com/en/tables2/

 

I would think that Salting is losing its value already?!

 

See, you are missing the point. You would need a rainbow table for every user. So therefore if you have 1000 users, you would need 5 petabytes to store all those rainbow tables. A (very fast) Google search puts the current hard drive market at $0.07/GB. So 5 petabytes would cost roughly $360,000 USD. Do you really think someone is going to invest that much money to hack your website?

 

I don't think you understood me, plus I have to disagree with what you are saying above somewhat.

 

From my understanding of Rainbow Tables, hackers are not only generating entries for "password", "LetMeIn", "guess" and so on, but they are gathering all sorts of combinations for potential passwords including "1234pass", "1234567890password" meaning that as Rainbow Tables grow they are in essence cataloging not only Potential Password, but Salted Potential Passwords...

 

*If* that is true, then Salts will need to grow longer and more complex.

 

Also, is the issue/question, "How many UNIQUE combinations can a Hash store?"  If I use our SHA512, how many unique values can it hold?

 

As Rainbow Tables get larger and larger, it will become harder to have a Salted Password that does NOT have a corresponding "Lookup Value" for it, right?

 

 

 

And so if I was a hacker, then I would have to use the same "Kicken Super-Duper Hashing Algorithm" to create my Rainbow Table, right  And so therefore, if it took 1 minute to hash each value, then it would take years to do the whole dictionary or whatever, right?

 

Yes.

 

What are the different Hashing Algorithms out there for use?

 

How do they compare as far as "slowness"?

 

 

 

And what would happen if I have a "Pass-Phrase" which was longer than the Hash itself (e.g. 500 Characters)?

 

It doesn't matter, the length of the hash would remain the same.

 

Would it be based off of the entire Super-Long Original Pass-Phrase, though?

 

Because if the Password was "This is a super duper long password that no one would ever hope to guess" but because of size constraints the Hashing algorithm only "hashes" off of a truncated version (e.g. "This is a super duper long password that") then that could increase the chances of collisions.

 

 

Debbie

 

 

Link to comment
Share on other sites

Are you saying a Collision is looking for MANY Passwords that create the SAME Hash?

 

No, a collision is when two separate strings create the same hash.

 

I think I just said that!  ;)

 

 

For example let's say the hash of "password1" is "7c6a180b36896a0a8c02787eeafb0e4c". A collision would be another value that also happens to have the hash "7c6a180b36896a0a8c02787eeafb0e4c".

 

Something like this, right?

Password		Hash
------------		-------------
LetMeIn			12345
Guess			98503
secure			98503

 

 

If so, how does that help a hacker?

 

Because if an attacker can regenerate a hash with another value, they could use that value to login. If the user's password is really "password1", but "blurgablur" creates the same hash then they can use that to login with.

 

I don't follow you.

 

So two Passwords work at creating the same Hash that is used to Log In someone?

 

How does that help anyone break in to a system via a Log In page?

 

Through the back-end database?

 

 

 

Hang on...  Is a Cryptographic Key the same thing as a Salt?

 

In this context it would be referred to as a "pepper".

 

Can it also be called "Vinegar"??

 

 

A salt is unique for each user, whereas a pepper is static. Moreover, they are not stored in the same location (one in the database, one in the filesystem) so both would have to be compromised.

 

Can the "Pepper" be stored in a variable in plain site in my code?

 

 

Earlier you posted this code...

function hash_password($password, $salt = null)
{
if (!is_null($salt))
	$salt = substr(sha1(uniqid(mt_rand(), true)), 0, 10);

// this should be a long, random string
// stored somewhere safe
$key = 'abcdef';

$hash = hash_hmac('sha512', $password, $key);

return array($hash, $salt);
}

 

I see a $key in your hash_hmac function, but where did the $salt go???

 

My apologies, I forgot to stick the salt in there. It would go here:

$hash = hash_hmac('sha512', $password . $salt, $key);

 

So that takes the $password that a User enters into a Web Form, combines it with a Randomly-Generated $salt, and then passes that to the hash_hmac function which creates a Hash from the $password + $salt and $key, right?

 

 

What size do you recommend for the Pepper?

 

Is there any practical point at which your Salt or Pepper are *too* long for SHA512??

 

Thanks,

 

 

Debbie

 

 

Link to comment
Share on other sites

I don't think you understood me, plus I have to disagree with what you are saying above somewhat.

 

From my understanding of Rainbow Tables, hackers are not only generating entries for "password", "LetMeIn", "guess" and so on, but they are gathering all sorts of combinations for potential passwords including "1234pass", "1234567890password" meaning that as Rainbow Tables grow they are in essence cataloging not only Potential Password, but Salted Potential Passwords...

 

That's not how it works. The hash would be different with a salt. Let me show you an example using MD5 (for simplicity). Let's say we have these users:

mysql> select * from users;
+----+------+----------------------------------+------------+
| id | name | password_hash                    | salt       |
+----+------+----------------------------------+------------+
|  1 | bob  | 8542aac12095692451d03024c1a4aac3 | kdo50fda65 |
|  2 | joe  | 93c7284d2e1bb88cb92e5587d07e7ef3 | 9klr4nvzw0 |
+----+------+----------------------------------+------------+
2 rows in set (0.00 sec)

 

Now, bob's password is "banana" and joe's password is "popsicle". The password_hash that you see is a combination of the plaintext password and the salt, IE: md5(bananakdo50fda65)

 

If I don't use a salt (as would be the case if you downloaded a rainbow table), the hashes would look like this:

md5(banana) - 72b302bf297a228a75730123efef7c41
md5(popsicle) - a0c73d7e9b0192500f2b9b16e575e89f

 

As you can see, they are not the same as the user's actual password hash. So simply downloading a rainbow table won't do you any good. It's possible that you could find a collision in the rainbow table but like I said, using better algorithms makes this very very unlikely.

 

 

*If* that is true, then Salts will need to grow longer and more complex.

 

A salts length or complexity really has no bearing on anything. The fact still remains that you need a rainbow table for each individual user. The salt could be 1 character, and you would still need a rainbow table for every user.

 

Maybe 100 years in the future when 500 Exabyte hard drives are the norm you can worry. But not for now.

 

 

Also, is the issue/question, "How many UNIQUE combinations can a Hash store?"  If I use our SHA512, how many unique values can it hold?

 

As Rainbow Tables get larger and larger, it will become harder to have a Salted Password that does NOT have a corresponding "Lookup Value" for it, right?

 

I'm not a cryptographer, so I'm not really sure. All I know is that you don't have to worry about it. I'm pretty sure sha512 has not been broken yet, so until that happens, you're fine. And when and if that happens, a better hashing algorithm will take its place.

 

 

What are the different Hashing Algorithms out there for use?

 

How do they compare as far as "slowness"?

 

Well, typically the more bits the slower it would be. That's not the only deciding factor, of course. Some hashing algorithms (like md5) are not built for security at all but for signature. For example, an md5 checksum of a file, so you know the contents of the file haven't been tampered with.

 

If you want uber slow, go with blowfish/bcrypt. You can use PHPass to implement it.

 

 

Would it be based off of the entire Super-Long Original Pass-Phrase, though?

 

Because if the Password was "This is a super duper long password that no one would ever hope to guess" but because of size constraints the Hashing algorithm only "hashes" off of a truncated version (e.g. "This is a super duper long password that") then that could increase the chances of collisions.

 

It doesn't truncate anything. There is no size constraint.

 

Something like this, right?

Password		Hash
------------		-------------
LetMeIn			12345
Guess			98503
secure			98503

 

Yes.

 

 

I don't follow you.

 

So two Passwords work at creating the same Hash that is used to Log In someone?

 

How does that help anyone break in to a system via a Log In page?

 

Through the back-end database?

 

In your above example, if someone's password was really "Guess" but "secure" generated the same hash, then either of those would log the person in. Since on the back end you are simply comparing hashes, so it wouldn't know the difference.

 

 

Can the "Pepper" be stored in a variable in plain site in my code?

 

Sure. The only way anyone would see it would be to gain access to the server and download the file.

 

 

So that takes the $password that a User enters into a Web Form, combines it with a Randomly-Generated $salt, and then passes that to the hash_hmac function which creates a Hash from the $password + $salt and $key, right?

 

Right.

 

 

What size do you recommend for the Pepper?

 

30-60 characters or so.

 

 

Is there any practical point at which your Salt or Pepper are *too* long for SHA512??

 

Not really, other than wasting memory/storage space if you have ridiculously long strings.

Link to comment
Share on other sites

I like using a unix timestamp as salt.  It's easy to generate, is useful in and of itself (it's not uncommon to want to know when a user registered for a site), and doesn't advertise itself as a salt column.  It's also generally unique for every user (unless you have two users who registered at precisely the same time, which is an incredibly rare phenomenon).  It's a nice solution for those small-to-moderate sized sites. 

Link to comment
Share on other sites

I don't think you understood me, plus I have to disagree with what you are saying above somewhat.

 

From my understanding of Rainbow Tables, hackers are not only generating entries for "password", "LetMeIn", "guess" and so on, but they are gathering all sorts of combinations for potential passwords including "1234pass", "1234567890password" meaning that as Rainbow Tables grow they are in essence cataloging not only Potential Password, but Salted Potential Passwords...

 

That's not how it works. The hash would be different with a salt. Let me show you an example using MD5 (for simplicity). Let's say we have these users:

mysql> select * from users;
+----+------+----------------------------------+------------+
| id | name | password_hash                    | salt       |
+----+------+----------------------------------+------------+
|  1 | bob  | 8542aac12095692451d03024c1a4aac3 | kdo50fda65 |
|  2 | joe  | 93c7284d2e1bb88cb92e5587d07e7ef3 | 9klr4nvzw0 |
+----+------+----------------------------------+------------+
2 rows in set (0.00 sec)

 

Now, bob's password is "banana" and joe's password is "popsicle". The password_hash that you see is a combination of the plaintext password and the salt, IE: md5(bananakdo50fda65)

 

If I don't use a salt (as would be the case if you downloaded a rainbow table), the hashes would look like this:

md5(banana) - 72b302bf297a228a75730123efef7c41
md5(popsicle) - a0c73d7e9b0192500f2b9b16e575e89f

 

As you can see, they are not the same as the user's actual password hash. So simply downloading a rainbow table won't do you any good. It's possible that you could find a collision in the rainbow table but like I said, using better algorithms makes this very very unlikely.

 

Okay, but this is where you weren't following me...  :)

 

So for Bob we have...

$password = 'banana'

$salt = 'kdo50fda65'

 

...which would yield...

$hash = '8542aac12095692451d03024c1a4aac3'

 

Right?

 

And a standard, run-of-the-mill Rainbow Table might have...

 

$password = 'banana'

$hash = '72b302bf297a228a75730123efef7c41'

 

 

But as Rainbow Tables grow and grow, what is to stop someone from doing this...

$password = 'banana'

$salt = 'kdo50fda65'

$password = $password . $salt

$password = 'bananakdo50fda65'

$hash = '8542aac12095692451d03024c1a4aac3'

 

 

Maybe that is so many combinations of characters that it isn't usable in 2012.  But if your Passwords were less than 6 characters and your Salts were only 4 characters, and as time goes on, then the above is certainly plausible, right?

 

That is what I was talking about...

 

 

*If* that is true, then Salts will need to grow longer and more complex.

 

A salts length or complexity really has no bearing on anything. The fact still remains that you need a rainbow table for each individual user. The salt could be 1 character, and you would still need a rainbow table for every user.

 

I don't disagree, but my point was that everything can still be precomputed.

 

 

Maybe 100 years in the future when 500 Exabyte hard drives are the norm you can worry. But not for now.

 

Okay.

 

 

Also, is the issue/question, "How many UNIQUE combinations can a Hash store?"  If I use our SHA512, how many unique values can it hold?

 

As Rainbow Tables get larger and larger, it will become harder to have a Salted Password that does NOT have a corresponding "Lookup Value" for it, right?

 

I'm not a cryptographer, so I'm not really sure. All I know is that you don't have to worry about it. I'm pretty sure sha512 has not been broken yet, so until that happens, you're fine. And when and if that happens, a better hashing algorithm will take its place.

 

What about bcrypt??

 

Is that a viable choice for PHP and what we are talking about?

 

(I've read that bcrypt is supposed to be even better...)

 

 

What are the different Hashing Algorithms out there for use?

 

How do they compare as far as "slowness"?

 

Well, typically the more bits the slower it would be. That's not the only deciding factor, of course. Some hashing algorithms (like md5) are not built for security at all but for signature. For example, an md5 checksum of a file, so you know the contents of the file haven't been tampered with.

 

If you want uber slow, go with blowfish/bcrypt. You can use PHPass to implement it.

 

I saw somewhere that phpass had already been hacked??  :o

 

 

Would it be based off of the entire Super-Long Original Pass-Phrase, though?

 

Because if the Password was "This is a super duper long password that no one would ever hope to guess" but because of size constraints the Hashing algorithm only "hashes" off of a truncated version (e.g. "This is a super duper long password that") then that could increase the chances of collisions.

 

It doesn't truncate anything. There is no size constraint.

Okay.

 

 

Can the "Pepper" be stored in a variable in plain site in my code?

 

Sure. The only way anyone would see it would be to gain access to the server and download the file.

 

Okay.

 

 

So that takes the $password that a User enters into a Web Form, combines it with a Randomly-Generated $salt, and then passes that to the hash_hmac function which creates a Hash from the $password + $salt and $key, right?

 

Right.

 

Okay.

 

 

What size do you recommend for the Pepper?

 

30-60 characters or so.

 

Oh, wow!

 

Do I need to generate that randomly or use any special scheme to generate it like the Salt?

 

 

Is there any practical point at which your Salt or Pepper are *too* long for SHA512??

 

Not really, other than wasting memory/storage space if you have ridiculously long strings.

 

Okay.

 

Thanks for all of your patience in answering my nitpicky questions!!!  :shy:

 

 

 

Debbie

 

Link to comment
Share on other sites

Okay, but this is where you weren't following me...  :)

 

So for Bob we have...

$password = 'banana'

$salt = 'kdo50fda65'

 

...which would yield...

$hash = '8542aac12095692451d03024c1a4aac3'

 

Right?

 

And a standard, run-of-the-mill Rainbow Table might have...

 

$password = 'banana'

$hash = '72b302bf297a228a75730123efef7c41'

 

 

But as Rainbow Tables grow and grow, what is to stop someone from doing this...

$password = 'banana'

$salt = 'kdo50fda65'

$password = $password . $salt

$password = 'bananakdo50fda65'

$hash = '8542aac12095692451d03024c1a4aac3'

 

 

Maybe that is so many combinations of characters that it isn't usable in 2012.  But if your Passwords were less than 6 characters and your Salts were only 4 characters, and as time goes on, then the above is certainly plausible, right?

 

That is what I was talking about...

 

The length and randomness of the salt is an unknown factor. I don't think it is technically feasible to generate a rainbow table that not only hashes every possible permutation of the ASCII table, but also generating it with every possible permutation of the ASCII table attached to it. You are talking about an astronomical file size, not to mention the YEARS it would take to do such a thing.

 

Put simply: this isn't going to happen anytime soon.

 

 

What about bcrypt??

 

Is that a viable choice for PHP and what we are talking about?

 

(I've read that bcrypt is supposed to be even better...)

 

It is certainly a viable choice. I think bcrypt was designed specifically for hashing passwords.

 

 

I saw somewhere that phpass had already been hacked??  :o

 

All I could find about PHPass being cracked is a brute force tool was released for it. Not a big deal really. I don't think you have anything to worry about.

 

 

Oh, wow!

 

Do I need to generate that randomly or use any special scheme to generate it like the Salt?

 

Yeah it should be a random string, but other than that nothing special. You can use this website to generate strings.

Link to comment
Share on other sites

From my understanding of Rainbow Tables, hackers are not only generating entries for "password", "LetMeIn", "guess" and so on, but they are gathering all sorts of combinations for potential passwords including "1234pass", "1234567890password" meaning that as Rainbow Tables grow they are in essence cataloging not only Potential Password, but Salted Potential Passwords...

Rainbow tables tend to focus on specific things such as dictionary words, or specific character sets.  While it's possible in theory that someone could create a huge rainbow table storing all combinations from one letter to several, it's not very practical in the real world.

 

Take for instance, say your form requires users enter a password at least 6 characters in length, and use use a 10 character salt.  That means the absolute smallest password you have would be 16 characters.  Now lets assume for some silly reason you decide users can only use letters and numbers (a-z, A-Z, 0-9).  Lets assume you keep the same restriction for your salt.  That means each of those 16 characters can be one of a set of 62 possibilities.  That means the number of combinations you would have to have in your rainbow table just to cover a 16-character string with those restrictions is roughly 4.52x10^74 (45,200,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000)

 

Assuming the simple md5 hash, to store that you'd need 32 bytes per entry (16 for the hash, 16 for the original value) for a total of 1,446,400,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 bytes (aka 1,196,434,037,996,699,228,934,005,532,209,994,271,397,590,637,207,031,250

yottabytes)

 

That could be somewhat optimized using collision checking and such, but still that is far more storage and processing power than anybody is going to have available.

 

 

Also, is the issue/question, "How many UNIQUE combinations can a Hash store?"  If I use our SHA512, how many unique values can it hold?

roughly 13,407,807,929,942,597,099,574,024,998,205,846,127,479,365,820,592,393,377,723,561,443,721,764,030,073,546,976,801,874,298,166,903,427,690,031,858,186,486,050,853,753,882,811,946,569,946,433,649,006,084,096

 

 

Would it be based off of the entire Super-Long Original Pass-Phrase, though?

 

Yes.  The entire input is used to generate the hash.  The output is just of a fixed size.  With sha512 for example, any input regardless of length will always generate a 64byte hash result.

 

 

Link to comment
Share on other sites

I like using a unix timestamp as salt.  It's easy to generate, is useful in and of itself (it's not uncommon to want to know when a user registered for a site), and doesn't advertise itself as a salt column.  It's also generally unique for every user (unless you have two users who registered at precisely the same time, which is an incredibly rare phenomenon).  It's a nice solution for those small-to-moderate sized sites.

 

I've heard of this before, and think you have a good idea!

 

Dumb question, but how do I get the Unix Timestamp in PHP?

 

And how do I convert it to a format that is more agreeable with a Salt?  (e.g. 123456)

 

Lastly, is there a way to "guarantee" that a Salt or Hash is unique by possibly appending an incremental value on the end, or would I not want to do that?

 

Thanks,

 

 

Debbie

 

Link to comment
Share on other sites

Dumb question, but how do I get the Unix Timestamp in PHP?

 

time();

 

And how do I convert it to a format that is more agreeable with a Salt?  (e.g. 123456)

 

It's just numbers, so no worries there.

 

 

Lastly, is there a way to "guarantee" that a Salt or Hash is unique by possibly appending an incremental value on the end, or would I not want to do that?

 

Well, you could generate a quick hash or something with microtime(). Unless two users register at the same microsecond, it should be unique. If you're concerned you can make it further unique by meshing it with parts of the users info. IE, their email, IP, username, etc.

Link to comment
Share on other sites

Rainbow tables tend to focus on specific things such as dictionary words, or specific character sets.  While it's possible in theory that someone could create a huge rainbow table storing all combinations from one letter to several, it's not very practical in the real world.

 

Okay.

 

 

Take for instance, say your form requires users enter a password at least 6 characters in length, and use use a 10 character salt.  That means the absolute smallest password you have would be 16 characters.  Now lets assume for some silly reason you decide users can only use letters and numbers (a-z, A-Z, 0-9).  Lets assume you keep the same restriction for your salt.  That means each of those 16 characters can be one of a set of 62 possibilities.  That means the number of combinations you would have to have in your rainbow table just to cover a 16-character string with those restrictions is roughly 4.52x10^74 (45,200,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000)

 

Assuming the simple md5 hash, to store that you'd need 32 bytes per entry (16 for the hash, 16 for the original value) for a total of 1,446,400,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 bytes (aka 1,196,434,037,996,699,228,934,005,532,209,994,271,397,590,637,207,031,250

yottabytes)

 

Hey!  Keep your YottaBytes to yourself!!!  :D

 

 

Yes.  The entire input is used to generate the hash.  The output is just of a fixed size.  With sha512 for example, any input regardless of length will always generate a 64byte hash result.

 

Don't you mean 128 Byte Hash? 

 

 

----

 

So based on everyone's comments, it sounds like hashing passwords using SHA512 correctly makes it pretty near impossible to hack the passwords??

 

Is that an accurate statement?

 

And, if I follow everyone's advice, then where are the "weak links" in protecting my User's Passwords?

 

 

Debbie

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.