Easy C++ BCrypt library

Started by
16 comments, last by rpiller 11 years, 3 months ago
What "token" are you referring too? The only thing on the server would be the MySQL encrypted column that holds the salt & hashed pw by user. If those are leaked then they have to decrypt the data first. If that's done then there isn't much you can do anyway for this game, but at least it's not plain text for them to try with other sites for the user.

I'm still not convinced you're doing it right.

Whether something is encrypted in MySQL doesn't matter, because your code needs to be able to read it, and thus an attacker will just insert the reading code into your code, or use some other code injection, to get the cleartext. Encrypted MySQL storage (or encrypted file systems) only protect against backups falling in the wrong hands, or physical theft, assuming the password itself isn't also stored on the machine.

So, let's assume you store bcrypt(salt, password) in the password database (is this what you mean by "hashed" ?)
Let's call this DatabaseValue.
This means the client needs to learn the salt, to be able to bcrypt it in the same way. So the client computes bcrypt(salt, password) and sends it to you.
You then compare it to DatabaseValue, and if it doesn't match, you deny the login.
This means that your login algorithm is insecure. If someone gets ahold of the password database, they can now log in as all possible users. They don't need to calculate anything, because the right response is already available. In effect, the hashed value is now the "cleartext" password, because knowing the value in the database allows you to login.

The whole idea of calculating a password hash is that leakage of the database table doesn't grant access to users. For this to work, the client MUST provide the cleartext password on login, and the server then calculates the hash and compares to the database value. Providing the hash from the client doesn't work, because the hash is not reversible.
If you are worried about the cleartext password leaking during transmittal to you, then use TLS. Your "additinal level of security" doesn't accomplish anything extra, and if it leads to the design above, then it actually hurts security.

If your design is somehow materially different, I'd be very interested in hearing a detailed description of what data is stored, what data is provided to the client, what data is provided from the client, and how login authentication actually works!
enum Bool { True, False, FileNotFound };
Advertisement
That's a good point. I guess I could double bcrypt it. One on the client, so the plain text pw isn't sent over, even when the wire is secure, and then the same as normal on the server like you say. This would add that extra layer I was thinking. Meaningless? Perhaps, but if the wire ever gets compromised this would at least mean no plain text pw goes beyond the text box they entered it in. Would just store 2 salts, 1 for the client bcrypt and 1 for the server.
That's a good point. I guess I could double bcrypt it. One on the client, so the plain text pw isn't sent over, even when the wire is secure, and then the same as normal on the server like you say. This would add that extra layer I was thinking. Meaningless? Perhaps, but if the wire ever gets compromised this would at least mean no plain text pw goes beyond the text box they entered it in. Would just store 2 salts, 1 for the client bcrypt and 1 for the server.

That's not the point. The plaintext password is irrelevant - all that matters is that without some sort of challenge-response system (as SSL/TLS does), whatever gets sent by the client on the wire is proof of authenticity, and can be intercepted by any sniffer. Then, the attacker can just copy that packet and send it himself to the server, and poof! He is now on your account, and you lost. No connection on the public internet is physically secure from eavesdropping. It's your job to make sure that even if an eavesdropper does eavesdrop, that he cannot read anything, or modify anything without being detected.

The attacker wouldn't obtain the actual password entered by the user, sure - but he doesn't need it in this case (though it is always good to make sure that password is hashed before being used anywhere, since many people use the same password on every website they visit).

As for salts, we assume that the database is distinct from the rest of the server, i.e. an attacker getting hold of the database does not have any direct access to user data - just the salted hashes. This is where the advantage of using a one-way function comes in, he still needs to go through the login process to access user data, and this requires him to... find a preimage of the database hash. And, then, in the worst case, perhaps he does have access to user data, but it's all encrypted. With? A key derived from... the preimage of the database hash.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

I will send over a secure connection but bcrypting on client and on server, bcrypt the bcrpty sounds more secure in the case the secure connection is compromised somehow or someway now or in the future. This way the clear text pw never makes it passed the text box. I don't like the idea of sending plain text pw anywhere ever in today we see a connection as secure.
bcrypt the bcrpty sounds more secure

If TLS is broken, the world has bigger problems than your particular game anyway :-) The math on the security just doesn't work out that way. Let's say your bcrypt() raises the risk of password exposure through broken TLS from 1:1,000,000,000,000 to 1:1,000,000,000,000,000 -- does this matter AT ALL? If you were to put a dollar amount (or relative time spent on the feature) to that change, how much is that worth?

Given all the possible attack vectors to your game, your obsession with client-side bcrypt seems to convey two things:
1) You think "more is better" in cryptography -- that's not necessarily the case.
2) Your priorities aren't considering the larger picture.

A social attack ("give me your password and I will power-level your character!") is 1000x more likely than a server-side crack. And a server-side crack is (my estimate) 1,000,000x more likely than TLS with good cyphers being broken. And this is for a popular game that people care about cracking -- what are you doing to make sure your game is fun, and becomes popular?
enum Bool { True, False, FileNotFound };
I'm using raknet and it has like TLS security, but isn't exactly TLS. I'm not going to change from using raknet, so I figure this will help some in the case raknet can be broken. Odds are my game won't be popular enough for anyone to care but adding this is est to take about a couple hours if that, so not long at all.

Also doing this do I really need TLS level of security? If bcrypt is good enough for if the db gets hacked shouldn't it be good enough for sending the bcrypted pw over the wire? It would take just as long to brute force if someone got it. If I implement some sort of expired pw system it wouldn't be hacked before the pw needs changing.

I'm not obsessed, I'm paranoid about storing passwords as its a big responsibility and so just looking at every angle.

Thanks for the help guys.
If bcrypt is good enough for if the db gets hacked shouldn't it be good enough for sending the bcrypted pw over the wire?

You clearly haven't actually understood what the cleartext on the wire attack is, nor what kind of problem bcrypt actually solves.

PLEASE re-read the descriptions I and others have posted above. If an attacker can snoop whatever is sent on the wire, they can log in, unless you use a cryptographically secure challenge/response algorithm -- but to do that, you need to store something in the database which, if the database were compromised, would leak the passwords.

You can't have both. Either defend against the database being leaked, or defend against TLS or RakNet being broken -- you logically cannot do both. I would defend against user database leak, because that's where all the public attacks have been. Also, just as likely is a key sniffer attack on the players' machine -- read up on what Maple Story has had to do for an illumination into what *actual* problems to solve are.
enum Bool { True, False, FileNotFound };
If an attacker can snoop whatever is sent on the wire, they can log in

If they hack the wire, yes they will be able to use that bcrypt'd value to log into just this game. If they hack the wire and the clear text pw is there they possibly now know the password for this person for multiple websites. My primary concern/fear is for the users password protection for other websites they may be using the same password for, not just my game. I am also defending on the database side, but doing this 1 extra step looks like it could defend on the other side for passwords that may be used in other spaces. My game is small and petty compared to a persons banking password. I'm not willing to just pass the blame onto them for using the same password, or more importantly being sued over it if such compromise happened!

You are correct my last comment was incorrect about not requiring wire security. I will continue to use RakNet's secure wire transfer system, but will also take the hour or so to implement this double bcrypt in the case the wire security for RakNet is broken somehow to protect against what could possibly be a pw used for other, more important, systems.

This topic is closed to new replies.

Advertisement