Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


Easy C++ BCrypt library


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
17 replies to this topic

#1 rpiller   Members   -  Reputation: 706

Like
0Likes
Like

Posted 03 January 2013 - 11:09 AM

I can't seem to find a good BCrypt library that's simple and cross-platform for C++. Anyone have any suggestions? Has anyone made any wrappers to any? On the website where players sign up for my game (which is .NET) I use http://bcrypt.codeplex.com/, which is so simple to use. I'm sort of looking for something to match this for my game client (which is in C++) so it can do the same when it bcrypt's the PW on the client and sends to the server for login validation.

 

I'm using RakNet for my networking and this login will be done over a secure connection, but I also want this extra layer because I don't want to store the actual PW of players on my server but instead the bcrypt'd value in case the DB becomes compromised in the future. I'll encrypt the DB field also, but this is just another layer of protection. Those 3 layers (secure connection, bcrypt pw, encrypted DB field) I would think would think would be enough protection. 



Sponsor:

#2 KnolanCross   Members   -  Reputation: 1368

Like
0Likes
Like

Posted 03 January 2013 - 04:12 PM

I believe openssl crypto module (http://www.openssl.org/docs/crypto/crypto.html) implements all you need. It is written in C, not CPP, but I believe you can easily warp it in a class, if you need some OOP feature.

 

Also, are you set in stone for this method?

 

The method I am using is (register):

 

1) Generate a random number.

2) Decrypt the password received by the client

3) Calculate a hash using the password and the random number

4) Save on the DB the random number (step 1) and the hash (step 3).

 

To authenticate:

1) Decrypt the password received by the client

2) Calculate the hash using the random number saved on database.

3) Check if saved hash match with the one I just calculated.


Edited by KnolanCross, 03 January 2013 - 04:13 PM.

Currently working on a scene editor for ORX (http://orx-project.org), using kivy (http://kivy.org).


#3 rpiller   Members   -  Reputation: 706

Like
0Likes
Like

Posted 03 January 2013 - 04:22 PM

I'll check that out thanks.

 

We are basically doing the same thing, but from everything I've read using a normal hash is bad practice as they are normally built for speed, which means most hackers can brute force them. BCrypt is slow on purpose and the speed can be changed with the increased speed of computers. I'm not sure if the "hash" in your flow is via BCrypt or not. Also I'm just adding another layer with the secure connection (RakNet basically does this for me, and encrypt the DB field which MySQL basically does for me), so it doesn't add that much overhead.



#4 Bacterius   Crossbones+   -  Reputation: 9289

Like
0Likes
Like

Posted 04 January 2013 - 12:24 AM

1) Generate a random number.
2) Decrypt the password received by the client
3) Calculate a hash using the password and the random number
4) Save on the DB the random number (step 1) and the hash (step 3).
 
To authenticate:
1) Decrypt the password received by the client
2) Calculate the hash using the random number saved on database.
3) Check if saved hash match with the one I just calculated.

Uh, I hope you are using SSL/TLS or something similar to transmit password information securely, otherwise this is vulnerable to a replay attack.


The slowsort algorithm is a perfect illustration of the multiply and surrender paradigm, which is perhaps the single most important paradigm in the development of reluctant algorithms. The basic multiply and surrender strategy consists in replacing the problem at hand by two or more subproblems, each slightly simpler than the original, and continue multiplying subproblems and subsubproblems recursively in this fashion as long as possible. At some point the subproblems will all become so simple that their solution can no longer be postponed, and we will have to surrender. Experience shows that, in most cases, by the time this point is reached the total work will be substantially higher than what could have been wasted by a more direct approach.

 

- Pessimal Algorithms and Simplexity Analysis


#5 KnolanCross   Members   -  Reputation: 1368

Like
1Likes
Like

Posted 04 January 2013 - 07:36 AM

1) Generate a random number.
2) Decrypt the password received by the client
3) Calculate a hash using the password and the random number
4) Save on the DB the random number (step 1) and the hash (step 3).
 
To authenticate:
1) Decrypt the password received by the client
2) Calculate the hash using the random number saved on database.
3) Check if saved hash match with the one I just calculated.

 

Uh, I hope you are using SSL/TLS or something similar to transmit password information securely, otherwise this is vulnerable to a replay attack.

 

Since he said he is using a safe conection, I didn't clarify this part. But yes, I am, RSA (2048 bits key) with PKCS#1 v1.5 to be more exactly.

 

On hashes, depends on the algorithm you are using. For instance, MD5 has been broken, but SHA2 and SHA3 haven't (link: http://en.wikipedia.org/wiki/Sha512)

 

EDIT:

In case anyone in the future is interessed using the python lib, here is the link to its documentation:

http://packages.python.org/pycrypto/

 

And the package, current versions as of the date of this post:

http://pypi.python.org/pypi/pycrypto/2.6


Edited by KnolanCross, 04 January 2013 - 07:44 AM.

Currently working on a scene editor for ORX (http://orx-project.org), using kivy (http://kivy.org).


#6 rpiller   Members   -  Reputation: 706

Like
0Likes
Like

Posted 04 January 2013 - 01:53 PM

 For instance, MD5 has been broken, but SHA2 and SHA3 haven't

 

I don't think it's about the breaking of the hash algo as a brute force hack isn't breaking anything, it's simply using computer power to try many combinations. Since it is my understanding that SHA2 & SHA3 are still fast algorithms hackers can brute force "really" fast. The faster the hardware gets over time the easier it is to brute force these fast hash algorithms. Look at this article: http://hackaday.com/2012/12/06/25-gpus-brute-force-348-billion-hashes-per-second-to-crack-your-passwords/

 

348 billions hashes per second!!! Fast hashing algo's just shouldn't be used for passwords, because the speed can always get faster which means the PW's can get hacked easier. I use BCrypt because you can control the speed of the algo, and can change it over time to keep up with the speed of computers.

 

Again, this is all my limited understanding of this space as it's a big and complicated space :)



#7 KnolanCross   Members   -  Reputation: 1368

Like
0Likes
Like

Posted 04 January 2013 - 03:51 PM

Even at that speed he would still take 2 years to calculate all the possible hashs. The main point of any cryptography search space is that it grows exponentially, while the attacker's power grows linearly.

 

Still, assuming he can "break" the hash by bruteforce in some fast way, he will only find the random number operated with the password, not the password itself (which is useless).


Edited by KnolanCross, 04 January 2013 - 03:54 PM.

Currently working on a scene editor for ORX (http://orx-project.org), using kivy (http://kivy.org).


#8 Bacterius   Crossbones+   -  Reputation: 9289

Like
0Likes
Like

Posted 04 January 2013 - 06:22 PM

Even at that speed he would still take 2 years to calculate all the possible hashs. The main point of any cryptography search space is that it grows exponentially, while the attacker's power grows linearly.

 

Still, assuming he can "break" the hash by bruteforce in some fast way, he will only find the random number operated with the password, not the password itself (which is useless).

 

If the attacker doesn't have access to your database, then it's fine. But if he does, then he has access to this random number, and can mount a standard brute-force attack on the password space, which is considerably smaller than the hash's entire search space, this is why you want a slow hashing function in case your database is compromised (and yes, saying "this will never happen" is an easy way to be sorry later on).


The slowsort algorithm is a perfect illustration of the multiply and surrender paradigm, which is perhaps the single most important paradigm in the development of reluctant algorithms. The basic multiply and surrender strategy consists in replacing the problem at hand by two or more subproblems, each slightly simpler than the original, and continue multiplying subproblems and subsubproblems recursively in this fashion as long as possible. At some point the subproblems will all become so simple that their solution can no longer be postponed, and we will have to surrender. Experience shows that, in most cases, by the time this point is reached the total work will be substantially higher than what could have been wasted by a more direct approach.

 

- Pessimal Algorithms and Simplexity Analysis


#9 hplus0603   Moderators   -  Reputation: 5723

Like
0Likes
Like

Posted 04 January 2013 - 06:31 PM

I still don't understand why the client needs to calculate the bcrypt.

If you receive bcrypt(password) from the client, and compare to stored(bcrypt(password)) on the server, then the token you store on the server, if it is leaked, is enough to gain access, and in effect becomes the plain-text password for an attacker.
enum Bool { True, False, FileNotFound };

#10 rpiller   Members   -  Reputation: 706

Like
0Likes
Like

Posted 05 January 2013 - 08:02 AM

I guess I view it as an extra layer of security when sending the password across the wire. If the wire gets hacked into at least they won't see the plaintext password since the player could be using that for other sites. If someone is able to hack the wire (even if it's thought to be unhackable today) at least it'll only be the hashed value for just this game. I view it as minimizing the already minimal risk and it doesn't introduce that much more work on my part. smile.png

 

If the wire is truly unhackable then no harm done, just minimal extra work.

 

 

 

 

then the token you store on the server

 

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.


Edited by rpiller, 05 January 2013 - 08:18 AM.


#11 hplus0603   Moderators   -  Reputation: 5723

Like
0Likes
Like

Posted 05 January 2013 - 11:04 AM

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 };

#12 rpiller   Members   -  Reputation: 706

Like
0Likes
Like

Posted 06 January 2013 - 07:30 AM

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.

#13 Bacterius   Crossbones+   -  Reputation: 9289

Like
0Likes
Like

Posted 06 January 2013 - 07:50 AM

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.


The slowsort algorithm is a perfect illustration of the multiply and surrender paradigm, which is perhaps the single most important paradigm in the development of reluctant algorithms. The basic multiply and surrender strategy consists in replacing the problem at hand by two or more subproblems, each slightly simpler than the original, and continue multiplying subproblems and subsubproblems recursively in this fashion as long as possible. At some point the subproblems will all become so simple that their solution can no longer be postponed, and we will have to surrender. Experience shows that, in most cases, by the time this point is reached the total work will be substantially higher than what could have been wasted by a more direct approach.

 

- Pessimal Algorithms and Simplexity Analysis


#14 rpiller   Members   -  Reputation: 706

Like
0Likes
Like

Posted 06 January 2013 - 08:12 AM

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.

#15 hplus0603   Moderators   -  Reputation: 5723

Like
0Likes
Like

Posted 06 January 2013 - 11:16 AM

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 };

#16 rpiller   Members   -  Reputation: 706

Like
-1Likes
Like

Posted 06 January 2013 - 11:39 AM

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.

#17 hplus0603   Moderators   -  Reputation: 5723

Like
0Likes
Like

Posted 06 January 2013 - 09:02 PM

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 };

#18 rpiller   Members   -  Reputation: 706

Like
0Likes
Like

Posted 07 January 2013 - 06:43 AM

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.


Edited by rpiller, 07 January 2013 - 06:47 AM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS