New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Storing user passwords #74
Comments
MD5 is indeed broken, especially if unsalted. There are even preimage attacks available (i.e. http://link.springer.com/chapter/10.1007%2F978-3-642-01001-9_8). bcrypt seems like a good idea. Unlike MD5 and SHA-1, there is no implementation in MySQL, but that's not a critical issue, security comes first, and neither of those two algorithms is secure enough for storing passwords. Another thing we should consider (unless we make bcrypt optional) is to get in touch with the most prominent Control Panel software authors to make sure they implement the new encryption algorithm in a timely manner. We don't want to drive away users because there's no easy way to manage their players' accounts. An implication of the algorithm change is that old passwords (if stored in MD5 format) will be no longer valid, and it won't be possible to batch-convert them. Thus, we might want to offer a way for the server to convert them on the first successful login. (And this is, as of today, outside the HPM capabilities, as far as I know.) The reason why we're currently allowing plain text passwords is because of the clientside (salted) hashing of passwords with certain versions of the login packet (see |
Ok... Thanks for pointing all this out. Here's the list of potential issues and possible solutions (proposed by you, and few more from me).
I'm gonna test more as soon as I prepare Linux build. Now, there are two factors to be taken into consideration when choosing work factor (number of rounds):
I suppose the second figure is usually rather low, unless you restart your server in peak hours. Even with 100 concurrent login attempts and 50ms per hash, it can delay user login by max 5 seconds. Anyway, that 50ms will imply different number of rounds depending on computing power available. So I guess there should be some kind of benchmark available to help determine number of rounds based on time limit imposed by user. |
About (1.A), I was thinking of a command line tool in src/tools (to easily compile with About (2), A and B are better from a security standpoint (why keep the unencrypted passwords, potentially for a very long time), but they may take a long time to complete in case of a big database, which may make option C more viable in certain cases. About (3), I feel that bcrypt(md5(password)) may decrease security. If I'm not mistaken, there are only 2^128 ~= 3.4E+28 possible MD5 hashes, while the possible passwords are much more than that:
About (4), it is really unfortunate that there's no control panel that works out of the box on Hercules. We really need to do something about that (but it's better to discuss that elsewhere, as it'd go off-topic here.) About (5), should we make it configurable (And perhaps provide a sane default value)? If we do, we need to warn the users that they should never change the value once they set it, or things will break. |
Suggestion for (5): How about making it configureable, but save the used number of rounds for each account. On each login it is checked if the config value matches the saved value and if it doesn't match, rehash the password and save it with the new number of rounds. So the admin can change it without breaking the login for all accounts. |
About your concerns for (3.A), I'm not really sure if they're justified. I found 3 topics related to the issue:
About (5), in case you change work factor old passwords (with different number of rounds) will continue to work, since that number is stored inside hash. They can't be rehashed to new factor without providing password though. You can even use higher number of rounds for some accounts (server, GM) that are most likely to be targetted first in case of security breach and lower for regular accounts. |
Hmm, I'm not sure who those people from the stackexchange topics are, so I can't really know whether they're security experts - but I agree with the point that bcrypt(md5(password)) is far better than keeping md5(password) entries. We can set it up so that those hybrid bcrypt(md5) entries are eventually replaced with bcrypt(password), when the user logs in. If we use bcrypt(md5) on existing md5 databases and bcrypt(password on existing plaintext or new ones, we'll need in any case to have the login server able to handle both, so it's a no brainer to have it detect if it should re-encrypt a password. (i.e. an algorithm like the one in the last flowchart from this example case) About (5), that is really good news. Thanks for clarifying. |
Preview of new console commands:
Example output:
|
I suggest to also salt the encryption using the login name. |
@Yommy I don't think using the login name as an additional salt would give any security improvements, as bcrypt already uses a random salt on every password (so that if two users have the same password, their hashes won't be the same.)
@piotrhalaczkiewicz What do you think of auto-detecting the password store method during password validation (i.e. calling |
@MishimaHaruna We used bcrypt to encrypt a 60k heavy userbase in one project. If the rounds aren't set too high you should only have a minimal downtime. |
is this issue dead? :( |
Just to let a note somewhere.
So basically, from my point of view, the md5 hash is as secured as plain password so we should really have another encryption method, any news on this branch ? |
@piotrhalaczkiewicz is on hiatus :/ |
Yes, md5 hashes are useless. It's not as easy as you describe, since only plain-text passwords are accepted if the server is storing hashed passwords in the database.
That was originally written because the packets But, in any case, I agree that the main point stands - MD5 is insecure and we should stop using it. The main reasons why this branch is stalled are:
|
If I remember correctly you can can omit to request a key from the server, in this case the key is never generated and so the md5 hash will not be salted. |
is the project of bcrypt is dead? |
How about this? I've added a pull request that adds support on windows. Client would have to send the password over in plaintext, unless someone can mod it to bcrypt on that end. Unless you want to bcrypt a md5 hash but that seems silly... Lib usage: std::string hash = BCrypt::generateHash(password, 10);
BCrypt::validatePassword(password, hash); Adding bcrypt on fluxcp should be simple enough. password_hash ( $password, PASSWORD_BCRYPT, [ 'cost' => 10 ] ); Notes on php:
|
I think the emulator is about time to have a feature like this |
Currently in Hercules there are 2 ways to store user passwords in database:
I've done little research on storing passwords in safe manner these days, and it looks like
bcrypt
is generally recommended and widespread solution. It also has ready to use implementations in many languages, most importantly PHP and C.I think we should provide a way to store passwords in a way that is considered safe. MD5 maybe was good enough several years ago, but with increasing computing power it no longer is.
The text was updated successfully, but these errors were encountered: