One, you don't use MD5 to "encrypt" or "store" your passwords. MD5 is a digesting or hashing function (hence the name Digest::MD5, which means that the process is definitely a one-way street: you can't undigest a hash value and learn what the original password was.

Two, while you're not concerned about "many users using the same password," you ARE concerned with the back end, where someone has access to your password store. This doesn't have to be direct database access or file access. Depending on protocol, this may also be a man-in-the-middle who might get to see unencrypted rsync activity from one server to another within your enterprise.

There are two key weaknesses in unsalted hashing: (1) someone looking at the hash values and deducing which users use the same password, and which users use different passwords, and (2) someone creating a useful dictionary of possible passwords and their associated hash value. Salt solves both concerns.

Let's compare passwords using three approaches. We show a table with the original passwords for several accounts, the password when passed through an encryption (and thus reversible) transform, the password hashed without salt, and the password hashed with salt.

I've picked a trivial function for encryption but more complicated ones would suffer the same vulnerability: figure out the key and you can unencrypt to restore the original passwords.

Users mary and joe use the same password, and you can see that with unsalted and encrypted password stores, but you can't see that with the salted store. If you used the unsalted store, then the a dictionary can list hash value 32F8ABC2 and the password "GoJets".

Okay, why is knowing common passwords a concern? If you wanted to socially engineer other things that only user mary can access, you might find talking to user joe to be a softer target, and user joe might leak other facts about user mary (her basketball team, her birthday, her dog, etc.) without anyone realizing it. Out of a list of fifty different users with forty-nine different passwords, the one guy who uses the same password is more likely your weak user joe.

Adding salt makes a dictionary have to store a much larger number of hash values for each possible password. Hopefully, with enough salt, the dictionary must be many terabytes or larger, which makes dictionary attacks far less tenable. Better encryption OR hashing functions will also make the hidden value longer, which is to reduce collisions (two different real passwords with the same hidden value), as well as make dictionary computation harder.

Update: Yes, salt must be chaotic/random to be of any use at all, it's really part of the definition of salt in this context.

When using MD5 one is not interested in reversing the digest in order to get the original value. Instead, one wants to apply the same method as the original and then compare the results to check if they match.

When I read the post I first thought it would be a web application, you are right to alert to the fact that there could be a middle-man in other scenarios, so there isn't much to do but to collect the information that comes from the browser and work with that. Given the wanted level of security, HTTPS should be considered.

I agree to your concerns on security, but in fact neglected the same values for different users, assuming integrity on DB level.
Still, salt won't solve the problem if it always the same, as it would give the same results for equal passwords. So, salt should be used and constructed in such a manner that it is different for each different user, but produces the same result for any given user. And you can do that while working with Digest::MD5.

There is a lot to say about security, and I am far from being an expert.
Thank you for your input.