How to properly store passwords (and some tips) 01-19-2017, 02:34 AM
#1
After sifting through pages of threads to make sure this tutorial wasn't already written, I'm kind of shocked it hasn't been. Storing passwords in a database is arguably one of the easiest things to get wrong when making a website, other than maybe forgetting to escape your input to protect against SQLi.
In all honesty, if you can avoid it, just don't store your users' passwords altogether and leave it to someone who knows how. That's not an insult to anyone's intelligence, for the record: if you can use some OAuth or some other kind of two-factor auth like signing in with Facebook or Google, it's likely to be much more secure than what you can accomplish. But if you must, and in some situations that's the reality, here's how. First, let's go over some ways you should not be storing passwords.
I seriously can't understand services that store passwords in plaintext. All it takes for potentially millions of emails and passwords to be sold then paraded around LF (ew) six months later is one tiny little slip-up. Sure, whatever service does this can just email you your password if you forget it, which is convenient, but that piles on so many more problems. Please god, don't do this.
This is what Adobe did prior to what happened back in 2013 (fun fact, 21383 of those passwords were "fuckyou"), and that ended very badly (probably because the whole thing was a giant crossword puzzle due to the password hints being stored alongside, but that's besides the point). Even using pgp doesn't guarantee your safety here, because once someone's broken into your database, it shouldn't take them too long to find where you're stashing your private key. Another problem with ciphers and encryption is that two users with the same password will have the same encrpyted string/ciphertext as their password, implying that a hacker found out all of those 21383 passwords said "fuckyou" in one go. Also don't do this.
Close, but no cigar. Hashing alone is a step up from all the previous attempts, since there's no key to keep track of, it's decently quick, and hashing a string is only a one-way function: there's no easy reverse. That said, there's tools like rainbowcrack that trade huge amounts of storage in the form of rainbow tables for negligible processing times, cracking any hash you throw at it provided your table is big enough (I recently learned that you can also just paste common hashes into google and it'll resolve them, but that's no fun). Additionally, there's a hole in some hashing algorithms called collisions, wherein multiple inputs to the algorithm can return the same output. Collisions aren't a huge problem for password storage, but they can still potentially be exploited by someone malicious. As with encryption and ciphers, the same passwords will look identical. You're getting there, but this still sucks.
Now that I've explained how not to do it, and how incredibly easy it is to fuck up, how do you do it right? Hashing and salting.
A salt is a random string of characters (not printable characters, per se) (I usually use 16, 12 if I want to throw people off a little) that is different for each and every user and is combined with the user's password before the pair is thrown into the hashing algorithm. This has all the benefits of hashing alone, and solves three very important things.
![[Image: gU5tMQ9.png]](http://i.imgur.com/gU5tMQ9.png)
A basic representation of how hashed and salted passwords are compared. Excuse my awful paint skills.
First, there's no practical way to crack the hash, even with rainbowcrack and google. Reversing something simple, say, "123456" or "password" is easy with either of those tools, but a- or prepend a 16-character string to it and neither program has half an idea about what it is.
Second, identical passwords are different when salted. Since every user has a unique salt, even if two users have the same password, it will be different when stored in the database.
Third, it's true privacy. Not even the database admin knows what your password is. Ever notice that Twitter, GitHub, and other sites ask you to reset your password instead of sending it to you? That's because they don't know what it is.
I won't go over how to do this, since I don't want anyone to try holding me liable for getting hacked when this tutorial becomes outdated (this kind of functionality should be kept updated every couple of months at least, anyway), but that's the basis on why you shouldn't store passwords altogether, how not to do it, and how not to fuck it up if you have to.
In all honesty, if you can avoid it, just don't store your users' passwords altogether and leave it to someone who knows how. That's not an insult to anyone's intelligence, for the record: if you can use some OAuth or some other kind of two-factor auth like signing in with Facebook or Google, it's likely to be much more secure than what you can accomplish. But if you must, and in some situations that's the reality, here's how. First, let's go over some ways you should not be storing passwords.
Plaintext
I seriously can't understand services that store passwords in plaintext. All it takes for potentially millions of emails and passwords to be sold then paraded around LF (ew) six months later is one tiny little slip-up. Sure, whatever service does this can just email you your password if you forget it, which is convenient, but that piles on so many more problems. Please god, don't do this.
Ciphers/Encryption
This is what Adobe did prior to what happened back in 2013 (fun fact, 21383 of those passwords were "fuckyou"), and that ended very badly (probably because the whole thing was a giant crossword puzzle due to the password hints being stored alongside, but that's besides the point). Even using pgp doesn't guarantee your safety here, because once someone's broken into your database, it shouldn't take them too long to find where you're stashing your private key. Another problem with ciphers and encryption is that two users with the same password will have the same encrpyted string/ciphertext as their password, implying that a hacker found out all of those 21383 passwords said "fuckyou" in one go. Also don't do this.
Hashing
Close, but no cigar. Hashing alone is a step up from all the previous attempts, since there's no key to keep track of, it's decently quick, and hashing a string is only a one-way function: there's no easy reverse. That said, there's tools like rainbowcrack that trade huge amounts of storage in the form of rainbow tables for negligible processing times, cracking any hash you throw at it provided your table is big enough (I recently learned that you can also just paste common hashes into google and it'll resolve them, but that's no fun). Additionally, there's a hole in some hashing algorithms called collisions, wherein multiple inputs to the algorithm can return the same output. Collisions aren't a huge problem for password storage, but they can still potentially be exploited by someone malicious. As with encryption and ciphers, the same passwords will look identical. You're getting there, but this still sucks.
The right way
Now that I've explained how not to do it, and how incredibly easy it is to fuck up, how do you do it right? Hashing and salting.
A salt is a random string of characters (not printable characters, per se) (I usually use 16, 12 if I want to throw people off a little) that is different for each and every user and is combined with the user's password before the pair is thrown into the hashing algorithm. This has all the benefits of hashing alone, and solves three very important things.
![[Image: gU5tMQ9.png]](http://i.imgur.com/gU5tMQ9.png)
A basic representation of how hashed and salted passwords are compared. Excuse my awful paint skills.
First, there's no practical way to crack the hash, even with rainbowcrack and google. Reversing something simple, say, "123456" or "password" is easy with either of those tools, but a- or prepend a 16-character string to it and neither program has half an idea about what it is.
Second, identical passwords are different when salted. Since every user has a unique salt, even if two users have the same password, it will be different when stored in the database.
Third, it's true privacy. Not even the database admin knows what your password is. Ever notice that Twitter, GitHub, and other sites ask you to reset your password instead of sending it to you? That's because they don't know what it is.
I won't go over how to do this, since I don't want anyone to try holding me liable for getting hacked when this tutorial becomes outdated (this kind of functionality should be kept updated every couple of months at least, anyway), but that's the basis on why you shouldn't store passwords altogether, how not to do it, and how not to fuck it up if you have to.
(This post was last modified: 01-19-2017, 02:38 AM by Inori.)
It's often the outcasts, the iconoclasts ... those who have the least to lose because they
don't have much in the first place, who feel the new currents and ride them the farthest.
don't have much in the first place, who feel the new currents and ride them the farthest.















![[+]](https://sinister.ly/images/modern/collapse_collapsed.png)










![[Image: 9H83e18.png]](https://i.imgur.com/9H83e18.png)
![[Image: 2zzkom1.png]](http://i68.tinypic.com/2zzkom1.png)


