md5 hashing using password as salt?

空扰寡人 提交于 2019-12-17 22:34:43

问题


md5($password.md5($password))

is this good enough for password hashing? I am not asking for comparing this to something like bcrypt.

if it is not secure, tell me why.


回答1:


The reason to use a different salt for each user's password is so that an attacker can't take a list of all the hashed passwords and see if any of them match the hash of something easy like "password" or "12345". If you were to use the password itself as salt, then an attacker could calculate md5("12345".md5("12345")) and see if it matched any entries.

As I understand it, there are four levels of hashing you can use on a password table:

  1. None - store the password as plain text. If someone gets a copy of your database, they have access to all accounts. Plain text is bad, 'mkay?
  2. Hash the password - store the hash of the password, and throw away the real password. If someone gets a copy of your database, they can't see any passwords, only hashes. However, if any users have used weak passwords, then their hashes will appear in rainbow tables. For example, if a user has the password "password", then an md5 hash stored in the database would be "5f4dcc3b5aa765d61d8327deb882cf99". If I look up that hash in a rainbow table like the one at gromweb.com, it spits out "password".
  3. Use a salt value - choose a large random string like a GUID and store it in your configuration file. Append that string to every password before calculating a hash. Now the rainbow table is far less likely to work because it probably won't have an entry for "password59fJepLkm6Gu5dDV" or "picard59fJepLkm6Gu5dDV". Although precalculated rainbow tables are not as effective anymore, you can still be susceptible if the attacker knows your salt value. The attacker can calculate the hash of a weak password plus your salt and see if any user in your database uses that weak password. If you've got several thousand users, then each hash calculation lets the attacker make several thousand comparisons. How you actually use the salt may depend on the encryption algorithm you're using. For simplicity, just imagine it as appending the salt and the password together.
  4. Use a distinct salt value - now you take something distinct like the user name, e-mail address, or even user id, and combine that with the password and the large random string from your configuration file before you calculate the hash. Now an attacker who knows your salt still has to recalculate the hash for every user to see if they have used a weak password like "password".

For more details, check out the Coding Horror post, "You're probably storing passwords incorrectly".




回答2:


Although it seems quite enough to me, it will be in danger in case if someone precomputed a rainbow table based on the same algorithm (what is quite possible). So, I'd rather use an email for the salt which seems pretty secure yet usable. Paranoids may add some constant site-wide salt.

People often makes too big deal out of password salt (in theory), while in their applications they allow simple passwords and transfer them in plain text over insecure HTTP in practice.

Every freakin' day I see questions regarding salt or hash.
And not a single one regarding password complexity. While

The only your concern should be password complexity.

Why? Let me show you.

extraordinary good salt + weak password = breakable in seconds

It is always assumed that salt is known to attacker. So, by using some dictionary of most used passwords and adding [whatever extra-random-super-long] salt to them, a weak password can be discovered in seconds. Same goes for brute-forcing short passwords.

just sensible salt + strong password = unbreakable

Quite unique salt makes precomputed tables useless and good password makes both dictionary and brute-force attacks good for nothing.




回答3:


It doesn't do much against dictionary attacks, only twice as hard to compute a dictionary versus a single md5, and md5 is pretty cheap these days.




回答4:


MD5 is not secure in itself because it is partially broken (collisions) and is too small of a digest anyway. If one doesn't want to use a proper password derivation function à la bcrypt, scrypt or PBKDF2 you should at least use SHA-256 for new designs (and have a plan to migrate to SHA-3 when it will be out, so be sure to store the scheme you used to hash the password with the result, so both scheme can coexist as you use the new hashing procedure when people change passwords).

If you intend to sell your program using MD5 in any capacity can be a show stopper for most government sales (e.g. in the US algorithms used must be FIPS 140-2 approved and many other countries got the same kind of requirements).




回答5:


The reason why random password salt is recommended for hashing password, so that an attacker who knows the password hash can't compare it to rainbow table of pre-calculated hashed from dictionary.

If you're using password as salt, attacker can pre-calculate hashes of $word.md5($word) first from their dictionary




回答6:


With your solution you pretty much defeats the purpose of using a salt against precomputed dictionary attacks.

With a precomputed dictionary, as the name implies, someone has already created a table of hashes (the computed md5 result) for particular words, ahead of time.

Consider this table hashtable (with imaginary hashes, just for illustration purposes)

word | hash
------------
foo  | 54a64
bar  | 3dhc5
baz  | efef3

Testing these values against your table, could be as simple as:

SELECT h.word
FROM hashtable h, yourtable y
WHERE y.password = MD5( CONCAT( h.word, h.hash ) );

With a match, you'ld have the password.

However, if you did NOT hash the password, before concatenating it again with the password and hashing it once more, it would be more difficult to attack it with a pre-computed dictionary. Because then the password would be for instance md5( 'testtest' ) which makes the precomputed table worthless, if the precomputed table has only taken into account single instances of the word.

You can easily see that it gets even more difficult if you did not use the password as a salt, but used another random string as salt. And it gets even more difficult still, when you create unique salts for every passwords. Of course, if you create unique salts per password, you'd have to save the salt in a separate column along with the passwords in a database row.

So my advice would be:

md5( 'uniquesalt' . 'password' );

Or actually, don't use md5 at all, but use the far better sha1, sha256 (or higher) hashing algorithms.



来源:https://stackoverflow.com/questions/5482437/md5-hashing-using-password-as-salt

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!