Everyone knows terms like one way hashes, digests, MD5 , encryption, decryption etc but not all people understand the nuances. what people understand is that you want to hide a message so you change the original message into a more difficult to read form. But as an application developer when do we need to use encryption/decryption and when do we use one way hashes?
You are going to use one way hashes when you never want to unscramble the original messages again. Think of authenticating the users. You only want to compare the user supplied passwords against what is stored in your database. So you first take the user supplied password ( when you created the login) , apply a one way hash on it (like SHA-1) and then store the hashed result in your database. when the user logins again, he supplied his password in plain text . You take the user supplied plain text password , apply the same hash function on it and then compare the result of hashing against what is stored in your database.
so schematically, at the time of login creation
when the user logins again , he supplies plain text password Q
then F(Q) should match F(P)
So here we do not compare P against Q. we always compare F(P) against F(Q). Now you can see that we are open to dictionary attacks in this scheme. I can guess your password, run it through a well known hash function and compare the results against what is stored in password database.
To foil such attacks we introduce something called salt. Salt is a sequence of random bytes, hashed and stored with the original password. The hashing function makes use of salt during hashing , so when given password P, we also generate a salt S and then store S and F(S,P) together in database. If someone is now guessing our passwords he has to guess the salts also.
Remember , we never talked about retrieving the original messages , i.e. plain text passwords. Now where do we want to use encryption/decryption? we typically use them in cases when we require to hide some data from prying eyes but need the plain text form inside our application. Say, given a message M, we can generate the encrypted message E(M) and display E(M) instead of M. When our application needs to read M, we apply a decrypt function D on E(M).
You are going to use one way hashes when you never want to unscramble the original messages again. Think of authenticating the users. You only want to compare the user supplied passwords against what is stored in your database. So you first take the user supplied password ( when you created the login) , apply a one way hash on it (like SHA-1) and then store the hashed result in your database. when the user logins again, he supplied his password in plain text . You take the user supplied plain text password , apply the same hash function on it and then compare the result of hashing against what is stored in your database.
so schematically, at the time of login creation
- plain text password = P
- F(P) => apply one way hashing function F on P
- store F(P) in database
when the user logins again , he supplies plain text password Q
then F(Q) should match F(P)
So here we do not compare P against Q. we always compare F(P) against F(Q). Now you can see that we are open to dictionary attacks in this scheme. I can guess your password, run it through a well known hash function and compare the results against what is stored in password database.
To foil such attacks we introduce something called salt. Salt is a sequence of random bytes, hashed and stored with the original password. The hashing function makes use of salt during hashing , so when given password P, we also generate a salt S and then store S and F(S,P) together in database. If someone is now guessing our passwords he has to guess the salts also.
Remember , we never talked about retrieving the original messages , i.e. plain text passwords. Now where do we want to use encryption/decryption? we typically use them in cases when we require to hide some data from prying eyes but need the plain text form inside our application. Say, given a message M, we can generate the encrypted message E(M) and display E(M) instead of M. When our application needs to read M, we apply a decrypt function D on E(M).
- D(E(M)) = M