It seems as though you understand that hashing is a one-way cryptographic function. A string hashed without a salt using a specific algorithm will always produce the same result. Hashes are not meant to be decrypted, they are meant to be compared to.
A string of
password hashed in MD5 without a salt will always be
5f4dcc3b5aa765d61d8327deb882cf99. When the user enters their password to enter the super secret website, their password value (in this case
password) is hashed, and compared to the hash that exists in the "users" table for that user. If the two hashes match then access is granted.
Because we know that a string's hash will always be the same without a salt, massive amount of strings hashes can be pre-computed in to what are called Rainbow tables. If a database gets compromised and no salt has been used, it is often trivial (depending on the algorithm and complexity of the password) to determine the password by comparing it to a hash that exists in the rainbow table.
By adding a randomly generating salt to the string and then hashing it, you make things exponentially harder to attack the hash with pre-computed rainbow tables. To do so, the attacker would have to guess what the salt would be, then generate their rainbow tables again. This becomes very inefficient and removes this as a viable option for password compromise.
So if our web application for my user-record has a salt of Sup3rS3cr3tS@l7, when I log in or change my password that salt will be appended to the password string. The value that is then hashed is
Sup3rS3cr3tS@l7password and the MD5 hash becomes
Salts do NOT need to be used globally - a salt can be randomly generated at account creation and stored in a column in the users table.
DISCLAIMER Don't use MD5, as this was purely for demonstration purposes.