Without going into too technical and mathematical detail, it might be useful to explain a little bit about the difference between _encryption_, _hashing_, and _salting_.
Encryption has been around for an awfully long time. The Egyptions used it to create mystery and amusement, and the Romans used it to send secret messages. When you encrypt a password, you apply some sort of algorithm which scrambles it up. Applying the key, unscrambles it.
ROT13 is a simple example of an encryption algorithm. It basically replaces each letter with one 13 places away in the alphabet.
Don't drink the wine. = Qba'g qevax gur jvar.
ROT13 is obviously quite a weak algorithm, but it's useful to illustrate the key point here - Encrypted data is reversible. It's like that by design. There's no point encrypting a secret message if the person at the other end is unable to decipher it. Therefore, it's useful for things like credit card numbers, or emails. The web browser you're reading this on is also using encryption.
The server encrypts the data, sends it over a secure SSL connection to your browser, which decrypts it so you can read it.
Hashing is different from encryption in that once the data is encoded, it can't be decoded. Well, at least it's extremely difficult to do so. Unlike encryption, the output is always of a fixed length, depending on the algorithm you use.
Using our phrase from before, and the MD5 algorithm we get ...
Don't drink the wine. = b290557177ec5dd7098d1de84616dd04
If we try a longer phrase ...
Please don't drink the wine, it tastes terrible. = fd870b20869d9ae05d84e3d7fbed0c94
You will see that the results are both the same length. This means, that multiple inputs could result in the same output, called a _collission_.
Hashing is useful when storing things which you don't need to read back, but you need to check. Passwords are the primary example. Instead of storing the clear text, you store the hashed version. Then, when someone types in their password, you apply the same hashing algorithm and compare it with what you have in the database. If they match, then the gates open.
Hash functions can also be used to test whether information has been tampered with. When sending an email, you first share a secret value that only you and the receiver know of. Before sending the email, you sign it with your secret value and produce the hash value. Then send your clear text email (without the secret value) along with the hash value. Your friend can then do the same process and if the hashes are the same, then they know your message hasn't been tampered with along the way. This technique is called Message Authentication Code or Hash Based Message Authentication Code.
The important factor for hashing algorithms is that they only work one way. The only way to work out the original value, is by brute force. Trying multiple values to see if they produce the same hash.
This is particularly problematic with passwords which are generally short and use commonly found words. It wouldn't take a modern computer very long to run through a large dictionary (or use existing rainbow tables) and figure out the hashed result of every common password.
That's where salting comes in.
Beside clogging up your arteries, salts can clog up anyone trying to crack a hashed password. They work by adding an extra secret value to the end of the input, extending the length of the original password.
Say your password is
rocky and the salt value is
i.love.salt. The hash value would be made up from both of these together
rockyi.love.salt. This provides some protection for those people who use common words as their password. However, if someone learns of the salt value you use, then they just add it to the end (or start) of each dictionary word they try in their attack.
To make this more difficult you can use random salts, one for each password. It obviously needs to be stored in the database somewhere matched up with the user account, but it does make brute force attacking much more difficult. Finally, you can create a salt from multiple parts, you can use the current date-time, the username, a secret phrase, a random value, or a combination of all of these.
This is only a very brief introduction to encryption, hashing, and salting. I've put links throughout the article for those of you who want more information.
If you only take one thing away from this introduction, it's not to encrypt user passwords, and don't rely solely on an un-salted hash algorithm. Ok, that's two things, but they're both important.