What is the optimum way to store passwords in 2021?

Viewed 3287

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 Users table 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:

  1. Do not rely on the inbuilt salt functionality of existing cryptography methods.
  2. Yes, utilize the existing salt functionality but this is no longer enough as a standard.
  3. You must create your own additional SALTS which thwart existing and mainstream tools.
  4. You must create 2 x additional and separate SALTS stored in 2 x separate places.
  5. SALT 1: Is a random and static secret stored locally in an environment variable or stored locally in a "secret file".
  6. SALT 2: Is a dynamic and random "user salt" stored within the DB and is password specific.
  7. SALT 3: Is the current salt you are already generating and storing and passing to bcrypt or similar.
  8. 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?

3 Answers

A lot of your research is correct and still applies in 2021, so it is still secure to use BCrypt (which usually generates its own random salt for each password). Good password hashing algorithms are Argon2, SCrypt and BCrypt, they all offer a cost factor which controls the necessary time.

There are some misunderstandings though.

  1. The salt is not obsolete, even if you can feed it to a cracker tool. Because each password has its own unique salt, the tool will crack just this one password and has to repeat the work for each other password instead of finding all in one go.
  2. There are no known salts as long as the password-hash function correctly used the random source of the system to create a unique random salt. It is absolutely impossible to do precalculations for all possible salts.
  3. It is best to let the password-hash function create the salt (not creating your own), because those libraries hopefully correctly read from the random source of the OS.

An additional encryption can be done after hashing, this is even the better choice than using a pepper. I tried to explain it at the end of my tutorial about safely storing passwords.

When you are storing passwords then always use:

  1. A SALT
  2. and PEPPER
  3. with bCrypt

Job done.

And thank you for all comments. My understanding is now clear which is what not before. Thank you Stack and contributors.

Your own passwords

If we are talking about our own passwords, then the best way to store a password is to remember it and not write it down anywhere, be it in a password manager, on paper or whatever.

If you must store a password digitally or on paper, then I would use a private cipher on my password before I store it - a book cipher for example.

In case your password store is hacked, your secret notebook containing passwords is stolen, or the like, then the thief would still not know the real password, nor the book used to encrypt it.

Other people's passwords

If we are talking about other peoples passwords, then you should only store an encrypted version, that can not be reversed AND require the password to be long enough, to take a long time to brute force AND store the salts for each password on another, more secure server. The algorithm you chose to encrypt passwords should NEVER be reversable.

Optimally you should outsource the authentication process to a trusted vendor and NOT store any encrypted-passwords, salts or seeds yourself.

Related