I store passwords, if you are a developer then it's easy to store passwords in which ever way is actually best. So I want to know, in 2021 which is the best? It's easy for me to tweak my code to become the best.
AND YES - I've researched and read many articles on Stack Overflow and other sites all offering the very best advice and I've followed it so this question is not a repeat of other threads.
A high level overview of what I currently do:
- Use SSL
- Use a bcrypt library
- Use a password strength library
- Generate / store a random unique salt every time
- Store as a SHA3_512
Which is the "learnt" wisdom from all of the articles and threads I've read.
BUT, just recently, someone told me that actually the above should now be considered insecure in 2021. Although this someone has good qualifications, I am nevertheless wary of making any security changes on a conversation and I am not a security expert so I thought before I make the changes then I must test it.
AND, I can think of no better place than Stack Overflow where I know it will be immediately cut to shreds if it deserves to be! I am not a security expert but it sounds believable enough that I am asking the question.
So I ask with some trepidation of looking like, and following some idiot that I believed, the following.... and yes I AM ASKING THIS not anyone else. Please find the logic I was presented with and I present to you ... eek!:
- If the
Userstable of your database has been compromised then your stored SALT has also been compromised (this is generally accepted from what I have read) - Hacker / password cracking tools are sophisticated, mature and rapidly evolve/adapt.
- The standard "hacker" password database has over 700 million of cleartext already used farmed passwords and their software creates clever variations producing rapid access to billions of likely possibilities.
- Standard hacking software already takes a "salt" input for bcrypt and PBKDF derivatives from an existing field within an existing compromised database therefore meaning the SALT becomes irrelevant. Effectively it becomes a command-line option to an existing tool which simply describes the algorithm and which field is the "salt".
- Further, these tools are now so sophisticated that they can quickly check the top x% of passwords with different "cost" values, different permutations of SHA digests to ascertain and analyze the actual combination used by the developer if they do not know it.
- So these "latest tools" are clever to the point of trying a whole number of commonly used techniques with the known salt against a selection of "likely targets" to actually determine if you used a SHA1/2/3 or what length and other stuff that I really just don't understand. But they are no longer stupid, actually they are very very clever.
- And these "tools" already exist and they are relatively easy to use with a ton of command line options so they are very accessible which massively broadens the attack vector.
So generating a random SALT using bcrypt or similar is longer secure as the tools have evolved past that. The salt doesn't actually make any difference anymore, as it is basically expected.
QUESTION 1: IS THE ABOVE ACTUALLY TRUE? (I personally have no idea at all)
And the recommended 2021 SOLUTION, apparently, is as follows:
- Do not rely on the inbuilt salt functionality of existing cryptography methods.
- Yes, utilize the existing salt functionality but this is no longer enough as a standard.
- You must create your own additional SALTS which thwart existing and mainstream tools.
- You must create 2 x additional and separate SALTS stored in 2 x separate places.
- SALT 1: Is a random and static secret stored locally in an environment variable or stored locally in a "secret file".
- SALT 2: Is a dynamic and random "user salt" stored within the DB and is password specific.
- SALT 3: Is the current salt you are already generating and storing and passing to bcrypt or similar.
- You then create your own unique formulae to generate the final encrypted password token.
ANALYSIS
- If your database has been compromised you are no longer subject to attack due to the local static secret.
- If your local scripts and database has been compromised then a copy of your scripts will not include ENV STATIC secrets which are needed to be attacked. You are no longer subject to attack.
- If you have been entirely compromised then the existing mainstream tools cannot be utilized for an attack as your customized system is still beyond the scope of current hack command line technology.
- If you have been entirely compromised then the bad actor would need to recode underlying hack tool source code to directly address your precise attack vector to utilize existing technology.
Something like as a possible unique salt example:
encrypted_real_user_password = Bcrypt ( SHA3_512 (
SHA1_256(static_password_stored_on_server) +
SHA2_512(plain_text_user_provided_password) +
CRC_32 ( (static_password_stored_on_server) + (plain_text_user_provided_password) ) +
SHA3_256(dynamic_password_stored_in_DB) ))
QUESTION 2: AM I AN IDIOT? (and please tell me if I am... I know you will!)
IN CONCLUSION
I really don't know what the response will be, try to be nice (as possible) and I hope in the end that if any small changes come from this to make my storing of passwords more secure then it will be worth it.
FINALLY FINALLY
Programmatically storing the encrypted password or "password token" as per the above is simple. A single line of code can encrypt and decrypt the password as per above.
BUT IS IT MORE SECURE?