DEV Community

Discussion on: Explain Hashing + salting Like I'm Five

Collapse
 
link2twenty profile image
Andrew Bone • Edited

Here's an example you're the owner of the data and I'm the nasty hacker.

Someone signs up for your site and uses the password 'password'
When you save it you MD5 hash it you get '5f4dcc3b5aa765d61d8327deb882cf99'
You now have no idea what the password is, a hash can't be reversed.

Let's say I get a dump of all your users and their encrypted passwords.
I make a script to test every common password, this includes 'password'.
Anyone can do a straight conversion to a MD5 hash so I have '5f4dcc3b5aa765d61d8327deb882cf99'

But you're smarter than I gave you credit for.
When the user created their account you took:

  • the date
  • their forename
  • your website name

and appended them to the password before you hashed it.

The hash has now been salted.
'password_20180816_andrew_dev.to' is the string that now gets encrypted
'9db61ea3e3b86adb63b507cb2a1b2951' is the output.

As I'm scanning through your files looking for '5f4dcc3b5aa765d61d8327deb882cf99' I go right past '9db61ea3e3b86adb63b507cb2a1b2951' and have no idea that's what I was looking for.

Of course, you need to remember the salt in order to convert their password into the hash for checking later.

Collapse
 
slavius profile image
Slavius

Points:

Hash itself can be reversed by using precomputed hashtables (aka rainbow tables). May be easier than you think. There are ways to compute and save hastables with considerable space savings thanks to packing.

The corect sentence should be: Hash function cannot be reversed.

Using a date/time in a salt is stupid idea. Salt must be some algorithm known constant so you can re-use it. If you use changing variable (like a datetime, unless it's immutable, like your birthdate) then you have to store it somewhere with relation to the hash so you can actually compute that hash again to compare it with user's provided password. It's like using user's firstname as part of the salt. It is too obvious and it's right next in the user's table in the database.

The best way is to keep the salt solely in your obfuscated code in memory and compressed and encrypted on the disk. Stealing the database does not then give too many information to guess the salt.

Collapse
 
brodan profile image
Brodan

I don't understand rainbow tables fully, can you explain how a good salt doesn't make them pointless?

Thread Thread
 
slavius profile image
Slavius

Let's imagine I am able to dump the Users table of your application using an undiscovered SQL injection error.

I will register as a user for your application and use password 'ABCD1234'.

Secretly your application appends '_S3cr3t!' to the plaintext password as a salt and caluclate a hash.

I will dump your database, find a hash of my password, feed it to JohnTheRipper with a mask of 'ABCD1234?????????' if not working then '????????ABCD1234'.
Just a matter of time (and money if I want a fast hashrate accelerated by GPUs) until I find a hash of 'ABCD1234_S3cr3t!' matches.

Then I build a rainbow tables of all hashes '[A-Z][a-z][0-9][special_chars1]{1-10}_S3cr3t!' to decrypt all hashes in your application.