This article will not lecture you on all the various variations of what you can do, or what you shouldn’t do even if you are already doing it wrong. Or how other authentication methods are superior when the “password” is ubiquitous.
No, this article, rather, delivers a definitive technical guide on what you should be doing right now to store your passwords in your database.
If you are not storing passwords already then this article may not be for you.
Let’s get to it… BUT, first check if the password you most often use has already been hacked as some organisation YOU trusted did not employ this simple technique below and guess what, they were HACKED!!
So.. OK.. let’s GO!
You must store “a password authentication token” in your database to validate against the “user entered password” on login or when registering.
The purpose of this token is that if, lord above, anyone ever obtained details of your database with say: emails, addresses and “password tokens” then you do not wish them to be able to reverse engineer that token to “original plain text password”.
SECURE PASSWORD TOKEN SYSTEM:
- User enters “plain text” password into your system using a secure protocol such as SSL.
- Next, you create a SHA-3 HASH of the plain text password from 1) above.
- Next add 64bytes to the start and end of the SHA-3 hash returned in 2) above in two 64 bytes chunks as below...
- 64 bytes are fixed and hard-coded or ENV within your application.
- 64 bytes are random binary, generated at run time, and stored against the user in your existing “system_user” database table.
- Add 64 x fixed bytes + 64 x random (but stored) bytes to the SHA-3 hash created in 2) above.
- Create new SHA-3 HASH of the original SHA-3 hash + 128 bytes.
- THIS IS THE NEW USER PASSWORD, so let’s encrypt it.
- Use Bcrypt (from a recognised library) to encrypt the user password as 8. above.
- STORE encrypted password in database.
WELCOME TO PASSWORD SECURITY!
Firstly, developers, companies get too caught up on which technology, cryptographic algorithm to use. Bcrypt is mature and industry recognised. Maturity always breeds security, use it.
With a recognized library… all languages have a bcrypt module.
But moreover, not many developers or companies approach it from a “hackers” view point.
HACKER 1: I’ve got hold of a new database of encrypted passwords with emails!
HACKER 2: F’king A man! Let’s process it for the top 100,000,000 passwords to start with.
Hackers rely on “highly intelligent brute force” using things like rainbow tables combined with a multitude of tools. If you just use Bcrypt and store that then this may look secure but it is not due to the level of sophistication and maturity of passwd crack tools.
So many organizations simply take your “plain text password” and then encrypt with say Bcrypt and store that…. that is a hackers wet dream.
And they are not so stupid to apply a SHA-3 hash of your compromised database just to see if you tried that old trick…. you probably didn’t but if you did, anyway, they are a step ahead of you. Bcrypt requires a “password salt” to operate, therefore hacking tools understand this and they understand the algorithm Bcrypt uses… so using the existing as provided salt functionality with a compromised database is like a knife through butter for a hacker. It does make it more difficult but their tools are already set up for that.
We outflank every password tool by adding two additional streams of information from two separate sources that we control…not Bcrypt, therefore the hackers must understand this to even consider attempting to compromise your passwords. So just having a CSV of the emails and passwords is no good, miles away.
They need a copy of the source code and they need to have analysed it. They needed to have extracted the 64 fixed bytes from it and applied it to the correct positioning of the SHA-3 hash.
We have also 64 bytes stored in the database… so now they need a fully compromised SQL dump of your system and they need to understand that they need to write a entirely new technique that when they attempt to brute force passwords they are mixing both a static piece of information and a dynamic piece of information that they need to look up from an SQL dump they’ve also acquired and they have re-coded their hack tools explicitly from this even if they can do that and understand even what they might do.
For the HACKER, it’s a total FUCKER.
For the DEVELOPER, it’s so EASY! (+1 hour on development time?)
You’re already storing the password, so just need to store one more thing… do a couple of calculations using libraries that already exist and when they login just replay back.
encrypted_real_user_password = Bcrypt ( SHA3_512 ( SHA3_256(static_password_stored_on_server) + SHA3_256(plain_text_user_provided_password) + SHA3_256(dynamic_password_stored_in_DB) ))