开发者

password storage in mysql for user content website

开发者 https://www.devze.com 2023-01-23 00:55 出处:网络
To store user passwords I am going to SHA 256 + salting. Just wanted to confirm if these are correct. Business requirement is password should be minimum 8 inputs and maximum 32 inputs. (any input is v

To store user passwords I am going to SHA 256 + salting. Just wanted to confirm if these are correct. Business requirement is password should be minimum 8 inputs and maximum 32 inputs. (any input is valid except blank space)

So to meet these requirements the plan is:

Front end - validate max input of 32 & min input of 8.

Backend the Database (MySQL) schema will be:

pass_hash(64) CHAR - store password hash

pass_slt(32) VARCHAR - store unique salt for each user

For salting I am not sure what value 开发者_高级运维to use as yet. But i think when users create an account I will create a random character for each user and use that. Then the other question is: Do i store the salt as plain text or need to hash/encrypt that too?

Also I dont know if it matters but can passwords support multi-language with this current plan or will I run into any issues? (I am talking about funky characters like Arabic, Chinese, etc)


On salts:

The salt is public data (if it was meant to be confidential then it would not be called a "salt" but a "key"). The salt must be known to verify a password (since it enters the hash function along with the password) so it is stored as cleartext, as you intend to do.

The point of the salt is to prevent an attacker from sharing attack costs between attack instances. Guessing a user-chosen password is often possible (users only have human brains and are rarely good at memorizing complex passwords). The salt makes sure that, at least, an attacker will have to pay the full price of password guessing (i.e. "trying" a big dictionary of possible passwords) for each attacked password.

The salt works well as long as it is unique for each password. Note that unique for each user is not sufficient: sometimes, users change their passwords, and you do not want the same salt to be used for the next password (otherwise, some level of cost sharing becomes available to the attacker). So you want the select a new salt any time a password is stored, i.e. when the account is created and whenever the password is changed.

Uniqueness of salts is easily ensured by using big enough random salts. 32-byte salts are more than enough for that: the risk of selecting twice the same salt (out of bad luck) is negligible.

An additional level of security, beyond salting, is to make password hashing "expensive". For instance, when you hash the (salted) password, you actually hash the concatenation of 10000 times the salt+password sequence. This makes password verification 10000 times more expensive, both for you and for the attacker. It is often the case that legitimate password verification can be made computationally heavier with no noticeable effect (even if you check 100 user passwords per second, you can still devote 100µs to that, and it will use only 1% of your processing time), but making things 10000 times harder for the attacker is a good idea.

On languages:

The main problem with non-ASCII passwords is that some glyphs may use several encodings. For instance, an 'é' can be encoded, with Unicode, as a single code point (U+00E9 LATIN SMALL LETTER E WITH ACUTE) or as two code points (U+0065 LATIN SMALL LETTER E, followed by U+0301 COMBINING ACUTE ACCENT). Note that this example is about a fairly common French letter, nothing as fancy (computer-wise) as Chinese or Korean. Encoding issues can be handled through Unicode Normalization Forms but this is not an easy programming tasks. Some programming environments can help (e.g., in Java, use java.text.Normalizer, which implements UNF).

Also, non-ASCII passwords can prove difficult to enter for users who switch keyboards, e.g. when the user wants to use a shared computer in an hotel or an airport (typing sensitive passwords on such systems is not a really good idea anyway).

I would recommend trying to enforce ASCII-only passwords if possible, or otherwise bite the bullet: perform UNF (with NFD form), then UTF-8 encoding. The resulting sequence of bytes is what goes to the hashing stage.


That looks about right, except that the salt should be fixed length (e.g. always 32 bytes); you're correct that it should be random and per-user. I don't see any real benefit to encrypting the salt. Salts defend against a scenario when the attacker already has a cleartext version of your database.

As far as multi-language, you should just be consistent about what character encoding you use in your application, and what exactly you're calling SHA-256 on.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号