I think this comic from CommitStrip says it all:
Passwords stored in clear text are half of the recipe to scary headlines such as “thousands of accounts published online by hackers”. To complete the recipe just add a single SQL injection or a good path traversal/LFI mix.
Mature and trained developers rarely make such mistake, why? Because they had training and understand the consequences. The problem is the others, which need to be self-taught.
So let me be very clear:
- you don’t need passwords in clear text to compare against the ones from login
- you can compare representations of them, lets say an hash
- never store or log passwords
Regarding the storing itself, there are way too many options [1]. I will recommend just one, which is adequate for most situations (if you feel this does not fits you, please contact the nearest security guy, or leave a comment):
function store(password)
salt = secureRandom(32bits)
hash = pbkdf2(salt, password, 10000)
storeAtDB(salt;hash)
end
function validate(user, password)
salt,hash = getUserFromDB(user).split(;)
login_hash = pbkdf2(salt, password, 10000)
if (login_hash XOR hash == 0 )
return true
else
return false
end
I won’t explain these in detail, but the basic idea is to store an hash of the password plus a salt. No, it is not easy to find out the password given an hash + salt. No, it won’t slow down your application. Yes, you will be much, much safer.
[1] https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet