Answer the question
In order to leave comments, you need to log in
What is the best way to encrypt passwords to store in a database?
How should the password be processed before putting it into the database?
Answer the question
In order to leave comments, you need to log in
In order to better understand the "how" and "why", the first step is to formulate the problem and consider solutions.
The challenge is to be able to verify the authenticity of the user's secret parameter without storing it, and without giving an attacker the opportunity to find out this very secret password.
For this, it is customary to use cryptographic hash functions, since their calculations are not reversible, and the set of output values has a distribution close to uniform.
Cryptography always works on the condition that all parameters of the system are open and known, except for the secrets themselves. That is, in the task of hashing a password , only the password is a secret, and all other parameters (salts, algorithms, hashes) are known. Accordingly, it is necessary to consider the situation that the attacker has absolutely everything - the hash base, the complete hashing algorithm and all its parameters.
Let's put ourselves in the place of the attacker now. With all this, how would we crack the password?
1. Rainbow tables (pre-generated "hash -> value" tables).
2. Dictionary attack (first, a search is made for the most probable values).
3. Full enumeration.
A complete enumeration will solve the problem 100%, but this is an extreme measure, extremely inefficient, and, as a rule, not working, because even though the password can be guessed for tens of thousands of years, the attacker will not live that long (as well as the hacked system itself, and user). Therefore, if we secured ourselves from points 1 and 2 somehow, then the task, consider, was solved.
If we just take some hash function (for example, sha256) and hash the password, we will do very badly. Why? Because the attacker, seeing this, will simply take the hash and substitute it in the rainbow table, and if the user did not bother with the password (and as a rule it is), then the password will be received almost immediately.
What needs to be done in order to exclude the option of using rainbow tables?
Make sure that the values supplied to the input of the hash function are guaranteed not to be in them. This is why salt was invented. In this regard, there is one simple requirement for salt: the salt must be difficult to guess .
That is, if we have a password "password" and a salt "111", then the probability of getting the string "password111" into the rainbow table is still very high, which means that such a salt is bad. But the salt "t%Lp-,DU4=w],9c7F.N$" is good, because no one will write the string "passwordt%Lp-,DU4=w],9c7F.N$" into the rainbow table.
Conclusion: We need a salt in order to eliminate hash lookups in rainbow tables .
If you also make the salt unique for each user, then even if all users use the same password, the stored hashes will be different. The advantage of this is that the attacker will have to hack each user separately in any case.
Conclusion: we make the salt unique for each user, so that hacking one user does not give access to others .
Further, in the attacker's arsenal there is a dictionary attack.
Alas, only the user can completely exclude this option if he uses passwords that are strong and difficult to guess, for which the probability of getting into dictionaries is "extremely small" (c).
But one should not hope for the prudence of all users, but somehow it is necessary to secure them. And here we still have the opportunity to "put a stick in the wheel" to an attacker by increasing the execution time of the algorithm. That is, we simply take and hash the result again eleven times, until the algorithm execution time becomes long enough, for example, 500ms. It is not a problem for us to wait 500ms when authenticating a user (and the user himself), but for an attacker to guess a password at a speed of 2 passwords per second, it’s already “oh-what-a-headache”.
Conclusion: we repeat the hashing many times in order to increase the execution time of the algorithm, which will slow down the selection of passwords .
This is, as it were, the whole general picture that an ordinary programmer needs to understand in order to solve the problem of hashing passwords.
You can delve into each of these points, and there are some troubles, but this is already a broader topic, interesting to "security guards" and cryptographers.
In order to implement all of the above, you don’t need to pull your hands to the bike, precisely because of the above “troubles” in the details of the algorithms. Cryptography does not forgive amateurism. Moreover, there are already de facto industrial standards.
For example, the bcrypt algorithm (thanks to kpa6uu for the mention). In PHP it is implemented through a standard password_hash()
function. Other languages also lack implementations.
Well, finally answering your question "what is the best?", then at the moment it is the Argon2 algorithm, winner of the latest Password Hashing Competition. With implementations in languages, unfortunately, so far everything is not as rosy as with bcrypt.
In each case its. The point is that they could not get the password, knowing what is in the database.
I think salt + RSA hash encryption will save you. RSA keys should be carefully stored...
Passwords are not encrypted, passwords are hashed. Very desirable with salt.
Salt can be the same for everyone (even in this form it is much better than without salt at all) or variable (depending, for example, on the date of registration).
The basic acceptable hash level is SHA-256, larger lengths are welcome.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question