Sign in to follow this  
rpiller

bcrypt usage

Recommended Posts

rpiller    839
What's the usage of bcrypt? I was using the HashPassword method but it's returning a different hash value every time for the same string. I'm using the .NET implementation but I'm guessing it's all the same method wise on how you would do this.

Share this post


Link to post
Share on other sites
rip-off    10976
Show us your code. How are you generating/storing the salt? Which implementation of BCrypt are you using, some light Googling suggests it isn't included with .Net.

Share this post


Link to post
Share on other sites
rpiller    839
It's not a native .NET library that I'm using. I think the salt thing was confusing me. I was under the impression I didn't have to have a salt, but it looks like I do. So that would mean I have to send the salt from the server to the client in order for the client to use bcrypt on their password and get the same exact value.

It seems dangerous to send the salt to the client because I have to do that just based on their username since the reason for sending them the salt is to they can bcrypt the pw on their side and then send that bcrypted pw back to the server to validate. So someone could get the salts of anyone pending they know their username. I thought it might be more like other hashes where you aren't required to have a salt.

Maybe sending the salt just based on username alone isn't that big of a deal?

Share this post


Link to post
Share on other sites
rip-off    10976
Step back, lets look at this from a different perspective. What problems are you trying to solve?

Server side hashing and salting [b]solves the problem where the user database is compromised[/b], making it much harder for an attacker to reverse the hashes back into plaintext for use in other services.

Client side hashing [b]solves the problem of someone sniffing the passoword on the wire, but only when used in "challenge/response" schemes[/b]. This cannot really be used with the above, because the server needs to do the same steps as the client, which means that the client needs to know the salt or the server needs to know the plaintext.

Sending the salt when given the user name effectively allows an attacker to remotely determine whether users exist, which may be bad enough from a privacy standpoint, but if the user name is an email address could easily lend itself to a phising campaign against your users.

A standard solution to the above problems is to send the plaintext password to the server across an encypted channel, and then use the standard salted/hashed user database on the server side.

Share this post


Link to post
Share on other sites
rpiller    839
Yeah that makes sense. I guess if a salt wasn't required that's what could be stored in the DB and the same hash could be done on the client and the username and hashed pw could be sent over to the server at the same time. I know the salt makes it harder to break but from my understanding of bcrypt the algorithm itself (without the salt even) makes it hard to break because it would be so time consuming that it wouldn't even be worth trying. My main concern is that I'm using a very simple sockets library built on top of .NET sockets, but I don't have access to any of the underlying socket information. It basically gives you events for when connected, disconnected, data arrived, etc. Then has methods like SendToAll(), SendToClient(), SendToServer(). It's very simple and amazingly easy to use (I've tried working with .NET sockets in an async mode and it's a pain. I want to focus on my game messages not the networking technology). So that being said I would have no idea how to or if I even could encrypt data going over via SSL (as I assume that would be the preferred method) with this library.

This networking library basically has you send a byte type to signify the msg and the "packet" data is just a string. I'm using this for lobby stuff for my game via .NET forms so I just csv values in the "packet". I created a BitStream class (much like RakNet which I know and love but getting it to work in .NET is a nightmare) but it just helps break out and write the csv string "packet". I'm doing this because using .NET GUI is much easier than making my own and the graphics library I'm using doesn't have one (Leadwerks). So the lobby area which is basically viewing matches, chatting, and changing some data about your "team" is done in this .NET GUI and when you start a "match" it launches a separate exe that is my actual game (done with Leadwerks). Passed to this exe will be a session id that is sent to the client from the server, and a "match" id that is also sent from server to client (thinking possibly IP address also to help avoid chances of spoofing). This actual game exe is going to use RakNet and Leadwerks in C++ and will connect to the game server (as opposed to the lobby server), validate session id against match id (which is stored in a DB on the server side, which was setup from the lobby) and then start playing the game.

So I guess a question would be, if bcrypt without a salt is still very time consuming to break (years from what I'm reading), then couldn't I just hardcode a salt value so that I can run bcrypt on the client side with this hardcoded salt value (basically making the salt useless but my thinking is bcrypt without salt is still years to break with brute force)? That way I don't have to send any salt to the client and that removes the phising possibility.

How much is being compromised by removing the salt factor in bcrypt seeing as the algorithm speed alone seems to be the key with bcrypt anyway. I've read some stuff about it possibly taking 12 years to brute force a bcrypt hashed value. So would removing the salt make that 6 years then (or something like that)?

Share this post


Link to post
Share on other sites
rip-off    10976
You can build an encrypted channel over such a system. A simple solution is to hard code the server's public key into the client. The client generates a (new, random) session symmetric key, and encrypts the password with this. It then encrypts the session key with the server's public key, and sends the two encrypted values to the server. The server can decrypt the session key, and then can then use this to decrypt the password. I wouldn't recommend this approach, only as a last resort, as you're effectively re-implementing parts of SSL. One bug could render your entire scheme useless.

I don't understand why you need to use this library you are talking about though. The lobby client probably doesn't need async networking. If you use standard HTTP for the lobby commications, you can use built in methods (e.g. WebClient). You can also avoid writing complex custom server socket code, you can use a pre-written HTTP server and something like PHP for handling the requests. This will probably scale far better than writing this yourself. It will likely be cheaper to host too.
[quote]
So I guess a question would be, if bcrypt without a salt is still very time consuming to break (years from what I'm reading), then couldn't I just hardcode a salt value so that I can run bcrypt on the client side with this hardcoded salt value (basically making the salt useless but my thinking is bcrypt without salt is still years to break with brute force)? That way I don't have to send any salt to the client and that removes the phising possibility.
[/quote]
I'm sitting next to you as you login. You type in your password, and then bcrypt() it. You send the resulting hash to the server. My computer is listening for network activity, and records your username and the bcrypted password. I can now access your account by sending the username and bcrypted password to the server at any time. I don't need to know your password, effectively the bcrypted password [b]is the password[/b].

The only advantage of this proposed scheme over sending the raw password is that I cannot directly use the hash to try login to other services where you might be using the same username/password.

There are two ways to mitigate this type of attack. One is to use a challenge-response protocol, the other is to encrypt the password. You could design a challenge response protocol where the client sends the username, you send the salt and a nonce to the client, which generates H(nonce, H(salt, password)). The server can verify this. As mentioned, this could lead to information disclosure about user names, and also potentially to phishing.

Share this post


Link to post
Share on other sites
rpiller    839
[quote]
I'm sitting next to you as you login. You type in your password, and then bcrypt() it. You send the resulting hash to the server. My computer is listening for network activity, and records your username and the bcrypted password. I can now access your account by sending the username and bcrypted password to the server at any time. I don't need to know your password, effectively the bcrypted password [b]is the password[/b].
[/quote]

I bcrypt the password twice (not sure if I mentioned that). I bcrypt just the pw, then I bcrypt that result with the session id that the server sends to the clients and is client specific and managed on the server. So the value I send over the wire is the bcrypt of the pw bcrypt'd with that result + session id (which changes every logon). What's stored in the DB is just the bcrypt of the original pw. Once I get the bcrypt pw + session from the client I do the same on the server since the server knows the session id of the calling client and can get the original bcrypt of the pw from the DB. The library I'm using actually sends that session id (Guid) as one of the parameters of the Data Received method so it's nice and simple to manage. I guess in that sense the session id (which is given on connect but not authorized) is acting as a salt. The difference being it changes on every logon.

So the process would go as:

1) Client does a connect to server
2) Server says I accept the connection but you aren't authorized to do anything yet
3) Client gets an event that says they are connected and asks for a session id
4) Server sends them a session id
5) Client bcrypt's their pw, then bcrypt's that result combined with the session id (the session id basically acting as a salt at this point) and sends that along with username
6) Server queries the DB on username, gets the bcrypt password, bcrypts that value + this clients session id to validate the 2 match and if so flags this client as authenticated on the server side. Future calls from this client send their session id (automatically from this sockets library) and everything they do in the lobby will check to see if they have been authorized.

(This is what I currently have implemented and working, but I just wanted to talk through the security of it)

So this seems safe as even if you were on the wire you wouldn't see the original bcrypt'd pw because that was bcrypted with a session id that changes on every logon. Spoofing the current session would be possible but not logging on at a time of the hackers choosing. I would think this would be plenty safe as most of these mid man attacks are probably not live attacks since they aren't going to sit and wait for hours/days waiting for you to log on. Even if they got some kind of notice the only thing they could do is mess with your current session of game data and this seems like an unlikely/uncommon problem and is not at least a major security risk on their overall personal data but just might mess with their video game data.

[quote]
I don't understand why you need to use this library you are talking about though. The lobby client probably doesn't need async networking. If you use standard HTTP for the lobby commications, you can use built in methods (e.g. WebClient). You can also avoid writing complex custom server socket code, you can use a pre-written HTTP server and something like PHP for handling the requests. This will probably scale far better than writing this yourself. It will likely be cheaper to host too.
[/quote]

I don't have much experience working with http or PHP or any other web stuff. All my networking experience is with RakNet or other UDP/TCP libraries and sending/processing custom messages.

Share this post


Link to post
Share on other sites
rip-off    10976
Well, you should really have described this earlier, the scheme you are talking about now is considerably different from the one I thought you might be doing.

By losing the salt, you lose one key feature of these algorithms. I can generate a table of common/weak passwords -> bcrypt hashes. When I see the protocol on the wire, I can brute force your password if it is weak by simply going through the hashes in the table, hashing them with the session identifier. There are also concerns about how the session identifier is generated. If it isn't designed to be secure, there is a risk in depending on it in your authentication protocol.

[quote]
I don't have much experience working with http or PHP or any other web stuff.
[/quote]
It is fairly easy. Arguably, it is easier and more secure than trying to write this yourself.

However, the point even stands without using these technologies. Your client shouldn't need async sockets, it could create a simple SSL socket. The server needs to be a little smarter if you expect high load. The great thing about defining your algorithm without depending on this library means that you could start out with a really simple .Net SSL server, and then move to something more advanced like an async version or a Node.js implementation as your load increases.

Share this post


Link to post
Share on other sites
rpiller    839
[quote]
It is fairly easy. Arguably, it is easier and more secure than trying to write this yourself.
[/quote]

I've done 1 of these at work and it required a certificate to be installed on our server machine. Is there ways to not require this? I've never played a game where it required me to install any kind of certificate so it could authenticate.

[quote]
Your client shouldn't need async sockets
[/quote]

But I can't have it blocking the UI, and it would be nice to avoid threads because I've had nothing but a pain updating a UI element from another thread. So I guess that's why the library I'm using was just nice because the events all fired in the UI thread and all that behind the scenes stuff was handled for me. I'm not sure how this normally would work otherwise with the SSL synchronous way.

I found [url="http://msdn.microsoft.com/en-us/library/system.net.security.sslstream.aspx"]http://msdn.microsof....sslstream.aspx[/url] example that looks to be what you are talking about. It's using a synchronous SSL TCP/IP connection. In this case the cert needs to be installed on the machine. At my work there is a couple processes where we actually load the cert via code from the .cert file path, which I suspect would be easier for the users, but I would have to ask, are games really doing this?

I suppose I could actually just do this for sign on and then go back to my other library (because honestly this other library is so much easier to use then sockets directly or even the TcpClient class in .NET), and in that case it could be blocking as no need to update the UI in the few seconds it's checking credentials.

With this library below is all I have to do. The library is [url="http://code.google.com/p/nading-network-library/."]http://code.google.c...twork-library/.[/url] It's older and doesn't look like it's being updated anymore which is a shame because on the todo list was "Dynamic automated encryption and decryption transparent to your code" . That would have been nice :)

[code]
client = new clsClient();

client.Connected += new clsClient.ConnectedEventHandler(client_Connected);
client.Disconnected += new clsClient.DisconnectedEventHandler(client_Disconnected);
client.PacketReceived += new clsClient.PacketReceivedEventHandler(client_PacketReceived);
client.Connect("127.0.0.1", "5000", false);

void client_PacketReceived(byte PacketType, string Packet)
{
}
void client_Disconnected()
{
}
void client_Connected()
{
}
[/code]

That compared to MS's example of reading data from the TcpClient class. In my view there is just no comparison in complexity. And the below code isn't even async. The complexity of adding that is even worse.

http://msdn.microsoft.com/en-us/library/system.net.security.sslstream.aspx

Share this post


Link to post
Share on other sites
sam_hughes    132
[quote name='rip-off' timestamp='1310319151' post='4833400']
There are two ways to mitigate this type of attack. One is to use a challenge-response protocol, the other is to encrypt the password. You could design a challenge response protocol where the client sends the username, you send the salt and a nonce to the client, which generates H(nonce, H(salt, password)). The server can verify this. As mentioned, this could lead to information disclosure about user names, and also potentially to phishing.
[/quote]

It's worth pointing out that this is a bit redundant. You're already sending a nonce, so why are you sending another value (a nonce?) (and calling it a "salt") with it? Having the server send just a nonce, and have the client send back H(nonce, password) is what [i]would[/i] make sense if not for the fact that it is a bad idea on an unencrypted channel for other reasons: Consider a third-party listening in. The third-party can see (nonce, H(nonce, password)) pairs. This is equivalent to a web server leaking its password database. If the algorithm H is in fact bcrypt, the attacker can crack a smallish percentage of passwords. (I would call it a "large" percentage.) (Of course, if the algorithm H is HMAC-SHA-256 or something, the attacker can crack a larger percentage.) So if you did use such a scheme you'd also want this to be over an already-secured channel. But once you've got that set up, just have the client send the password.

[quote=rpiller]I've done 1 of these at work and it required a certificate to be installed on our server machine. Is there ways to not require this? I've never played a game where it required me to install any kind of certificate so it could authenticate.[/quote]

This doesn't seem like a problem. You can generate a certificate yourself, and it can be self-signed, since the client can have the public certificate pre-distributed or just as a special case accept a certificate with a particular fingerprint.

Share this post


Link to post
Share on other sites
rip-off    10976
[quote]
It's worth pointing out that this is a bit redundant. You're already sending a nonce, so why are you sending another value (a nonce?) (and calling it a "salt") with it?
[/quote]
To allow the server store the hash of the password, rather than requiring it to store the plain text.

[quote]
This is equivalent to a web server leaking its password database.
[/quote]
Yes. That is why I would prefer an encrypted approach.

[quote]
I've done 1 of these at work and it required a certificate to be installed on our server machine.
[/quote]
That is to get the certificate to work with other applications, e.g. browsers. In your own program you don't necessarily need a certificate, you could simply hard-code the public key you want to use.

[quote]
But I can't have it blocking the UI...
[/quote]
Then use non-blocking sockets. They are different from asynchronous sockets, and are generally easier to use. Again, remember to use the right tool for the job - the problems asynchronous sockets solve are generally server side, dealing with many simultaneous clients.

Share this post


Link to post
Share on other sites
rpiller    839
[quote]
Then use non-blocking sockets
[/quote]

I thought the only way to get non-blocking sockets was to either use the async methods of the sockets or multiple threads with the blocking sockets? How do you get non-blocking sockets without those 2 approaches?


[quote]
you could simply hard-code the public key you want to use.
[/quote]

How do you get these keys? Is there a program to generate them for Windows? If the key is the same and is on the client machine which a hacker would know, how does that make it more secure? What is SSL doing that a man on the wire still wouldn't be able to decrypt the msg?

I think I've decided to use SSL with TcpClient for logging in, and once authenticated switch over to this other library. I'm just more comfortable with this other library in terms of using it for chat and other game related messages and once the security risk is handled with the login will switch to using it. Just need to figure out how these keys are generated and more info about SSL.

Share this post


Link to post
Share on other sites
rip-off    10976
[quote]
How do you get non-blocking sockets without those 2 approaches?
[/quote]
Using something like [url="http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.blocking.aspx"]this[/url]. You still must actively poll the socket though, but now you can ensure that polling will not block your GUI thread.

[quote]
How do you get these keys? Is there a program to generate them for Windows?
[/quote]
You can probably use something like openssl. C# probably contains methods to generate keys, [url="http://msdn.microsoft.com/en-us/library/5e9ft273(v=vs.71).aspx"]this looks like it might help[/url].

[quote]
If the key is the same and is on the client machine which a hacker would know, how does that make it more secure?
[/quote]
Because it uses asymmetric cryptography. That is, the key used for encryption is different from the key used for decryption. Essentially, it is mathematically infeasable for an attacker to produce the decryption key from the encryption key. For more information, read about [url="http://en.wikipedia.org/wiki/Asymmetric_cryptography"]Asymmetric cryptography[/url].

[quote]
What is SSL doing that a man on the wire still wouldn't be able to decrypt the msg?
[/quote]
SSL uses asymmetric cryptography to establish a shared symmetric key between the client and server. This key is only used for this session. For more information you'll need to do some research yourself, if I try explain it any more I'll probably get something wrong.

[quote]
I'm just more comfortable with this other library in terms of using it for chat and other game related messages and once the security risk is handled with the login will switch to using it.
[/quote]
That is fine. Just remember that once you've switched over that the session identifier is untrusted (anyone can make a request using the given session identifier). It should only be used for session related activities, which means that any attack on it can only corrupt the current session.

In particular, do not allow the client access to sensitive information using just this "session identifier", which could later compromise the authentication mechanism. For example, changes to the username/email address or password should probably only be allowed if the client re-submits its current password.

Share this post


Link to post
Share on other sites
rpiller    839
Thanks for all your help. You were great.

[quote]
That is fine. Just remember that once you've switched over that the session identifier is untrusted (anyone can make a request using the given session identifier). It should only be used for session related activities, which means that any attack on it can only corrupt the current session.

In particular, do not allow the client access to sensitive information using just this "session identifier", which could later compromise the authentication mechanism. For example, changes to the username/email address or password should probably only be allowed if the client re-submits its current password.
[/quote]

That makes sense and is what I was thinking. After authentication it's just game related stuff that doesn't really need to be secure in terms of security risks, but does leave open the ability for someone on the wire to mess with that players game data. I can't imagine many games really write everything on a secure socket with general game data though as I'm sure it adds more time to the process and generally time is critical. So I would think most games are vulnerable to man on the wire attacks on game data but you don't really hear that very often. So it must either not be easy to get that setup or if they do they aren't doing it to just mess with game data but seeking sensitive data.

Share this post


Link to post
Share on other sites
hplus0603    11347
[quote name='rpiller' timestamp='1310404958' post='4833847']
So I would think most games are vulnerable to man on the wire attacks on game data but you don't really hear that very often. So it must either not be easy to get that setup or if they do they aren't doing it to just mess with game data but seeking sensitive data.
[/quote]

Google "firesheep" sometime for an eye-opening experience. Don't use Facebook or Twitter in a coffee shop...

SSL traffic adds close to zero overhead to an established connection. However, it does add significant additional computation needed to open a new connection, both in the form of CPU load and in networking round trips. Single-threaded proxies seem to have an especially hard time dealing with this, for obvious reasons. A hardware load balancer in front, doing target port re-writing may help, so you can run one proxy instance per core on your servers.

Assumed network structure:
(internet) <--> (HWLB doing DNAT) <--> (SSL proxy) <--> (application server)

Share this post


Link to post
Share on other sites
rpiller    839
I think I've figured out an alternative which allows me to still use my string based network library while providing really good security. In .NET I'll use RSACryptoServiceProvider (this is Asymmetric) to encrypt the data and send the data over the wire as encrypted text and decrypt it on the server side using the private key.

I'll make an object instance of this RSA class (which has the private and public keys in it, unique per instance) for each client so no 2 clients are alike and every new session would get new encryption keys to work with so as to make it a moving target.

When a client connects I'll send over their public key first so they can encrypt all data they send including their password to login. I'll probably still bcrypt thier password before encrypting it just to add that extra layer.

This is kind of "rolling my own" but not really since the important pieces I'm using trusted and proofed techniques.


As I'm talking this out it seems like SSL would still be vulnerable for session hijacking wouldn't it? I mean even if the data is encrypted the public key for Asymmetric encryption is known so it would seem a man in the middle could still send messages encrypting the data with the public key.

Share this post


Link to post
Share on other sites
hplus0603    11347
[quote name='rpiller' timestamp='1310942761' post='4836523']
As I'm talking this out it seems like SSL would still be vulnerable for session hijacking wouldn't it? I mean even if the data is encrypted the public key for Asymmetric encryption is known so it would seem a man in the middle could still send messages encrypting the data with the public key.
[/quote]

Session hi-jacking requires that you can DECRYPT the data being sent, which means that you need the private key, which presumably is stored safe on your server. If it's good enough for banks, it's probably good enough for your game :-)

There is an initial symmetric key exchange, though, so in reality, when the session is established, a 128-bit or better symmetric key is established for a faster cypher like AES; only this key needs to be protected by the server certificate.

And it sounds to me as if you really should just use SSL, which also has pre-made components available. Don't roll that part yourself at all.

Share this post


Link to post
Share on other sites
rpiller    839
[quote]
Don't roll that part yourself at all.
[/quote]

?? I'm not really rolling anything myself. Using .NET framework to do it all really.

[quote]
Session hi-jacking requires that you can DECRYPT the data being sent,
[/quote]

?? Wouldn't it also include sending encrypted data? Since there is a public key you'd think you would be able to encrypt the data and send whatever hijacking commands you'd want to do. I suppose if the session key was encrypted too the man in the middle wouldn't know what it is to encrypt. Although that would mean the server is sending encrypted data to the client which would reverse public/private keys meaning every client would know how to decrypt the server msg making it worthless to even encrypt. So that's interesting.

Found a site that gives a good analogy but seems responses from the private key holder aren't very secure as anyone with a public key can decrypt it. Although it seems it makes sure the msg was sent from the correct place and not sent via a man in the middle, it doesn't make it secure.

[quote]
In “public key cryptography”, each person has two keys — a “public” key and a “private” key. Anything encrypted with the user’s public key can only be decrypted with the private key and vice versa. Each person then tells the world what his public key is and keeps his private key safe and secure, and private.

If John sends Mary a message encrypted with Mary’s public key, then [i]only Mary can open it[/i], as only she has her private key. This is like an envelope that anyone can seal but which only Mary can open.

If John sends Mary a message encrypted with John’s private key, then [i]anyone can open it[/i], as everyone has access to John’s public key. However, successfully opening the message proves that it was sent by John and no one else, as only John has access to his private key. This is like an envelope that only John can seal, but which anyone can open and thus prove that John sealed it.

In “public key cryptography”, each person has two keys — a “public” key and a “private” key. Anything encrypted with the user’s public key can only be decrypted with the private key and vice versa. Each person then tells the world what his public key is and keeps his private key safe and secure, and private.

If John sends Mary a message encrypted with Mary’s public key, then [i]only Mary can open it[/i], as only she has her private key. This is like an envelope that anyone can seal but which only Mary can open.

If John sends Mary a message encrypted with John’s private key, then [i]anyone can open it[/i], as everyone has access to John’s public key. However, successfully opening the message proves that it was sent by John and no one else, as only John has access to his private key. This is like an envelope that only John can seal, but which anyone can open and thus prove that John sealed it.

[/quote]



This looks to be a little excessive. I have to go through this 3rd party companies and pay a heft fee?

[quote]
[list][*] A company wishes to secure communications to their server company.com.[*] They create a public and private key for company.com (this is also known as as “[url="http://luxsci.com/extranet/ssl.html"]SSL Certificate[/url]“).[*] They go to a trusted third party company such as Thawte or Verisign: Thawte makes the company prove its identity and right to use the company.com domain. This usually involves a lot of paperwork and paying a hefty fee.[*] Once the verification is complete, Thawte gives the company a new public key that has some additional information in it. This information is the certification from Thawte that this public key is for the company and company.com and that this is verified by Thawte. This certification information is encrypted using Thawte’s private key… we will see why below.[/quote][/list]


This part seems interesting. So this Asymmetric part is only used at first to validate the pw of the client and for the client to send over a secret "password" to the server so that can be used to encrypt further data Symmetrically. Very interesting.
[quote]
[list][*]Once the client is happy with the server (and the server with the client, if needed), then the client choose an SSL Cipher to use from the list of encryption methods provided by the server, and generates a “symmetric key” (password) for use with that Cipher. The client encrypts this password using the server’s public key and sends it back to the server. The server (and only the server) can decrypt this message and get this password, which is now shared by both the client and server.[*]The client will then start communicating with the company by encrypting all data using this password and the chosen Cipher. Normal “symmetric” (password-based) encryption takes place from this point forward because it is much faster than using the public and private keys for everything. These keys were needed to enable the company (and possibly the client) to prove its identity and right to domain.com and to enable the client and server to generate and securely communicate a common password.[/list]
[/quote]

Share this post


Link to post
Share on other sites
rip-off    10976
[quote]
?? I'm not really rolling anything myself. Using .NET framework to do it all really.
[/quote]
Getting security correct is [b]hard[/b]. There are uncountable tales of people - even when they know what they are doing - messing this up.

SSL is the closest thing to "it just works" in security. It isn't perfect, there are still lots of issues about securing the login server and process that you have to take care of. For example, if this library you're using it vulnerable to buffer overflows or other remote exploits it could be attacked and compromised and you would find your private key and user database stolen.
[quote]
This looks to be a little excessive. I have to go through this 3rd party companies and pay a heft fee?
[/quote]
No. But you need an out-of-band authentication mechanism to avoid man in the middle attacks.

In your case, the simplest out-of-band solution is to bundle a particular public key with your application (hoping you never lose your private key or have it stolen).

For web browsers, it is unfeasible to "bundle" every possible public key for all websites you're going to visit, so this is why certificate authorities are used. Most examples you'll find online are people securing a website (or more usually, a single web form like a "login" page), so naturally you'll find most examples will assume you're going to a third party to sign your certificates.

The security provided is arguably non-existent, there have been high-profile cases recently which have threatened the foundations of this model -which were never strong anyway. In early security literature, the "trusted third party" was assumed to be something like your friendly local sysadmin, who has more or less control of the network anyway.

Fortunately or unfortunately, people don't understand SSL. [url="http://groups.google.com/group/mozilla.dev.security.policy/msg/a9cddc745f4ed8e6"]This post[/url] essentially shows what people thing SSL does. This means they mostly aren't aware of these problems, so they feel comfortable shopping online.

Share this post


Link to post
Share on other sites
rpiller    839
[quote]
In your case, the simplest out-of-band solution is to bundle a particular public key with your application (hoping you never lose your private key or have it stolen).
[/quote]

Yeah I was thinking about this more. I originally was going to have the server send this public key but realized the man in the middle could intercept the server msg and send his own public key. They they could intercept the reply and decrypt with their private key and get the information. So like you said I think I'll add the key information to the client. Of course if they ever get some software on the client machine I'm sure they could alter that key to do the same thing but at least that would be harder. I suppose if the private key is compromised I'd have to give a new exe. To avoid this I was thinking of putting the public key in a text file, but again that might be "easier" for a hacker to change to his own public key on another persons PC so he could decrypt the information. I would think this is all true for SSL also but it's all pending getting something on the users PC which is just out of my control and doesn't seem like there is much you can do there anyway. I suppose if they did get something on the users PC it would be easier to just have it be a keylogger.

Share this post


Link to post
Share on other sites
rip-off    10976
You've no real way to provide any guarantees about what is on the client machine. I could take your client executable, modify it so that it directs logins through a server I provide, and then distribute it myself. The best you can usually do is to post hash values of the client executables on your website. The problem is that 97% of users don't know what a hash is, and even the few technical people might not be inclined to check them.

You obviously then need to secure your website too so that someone doesn't swap the executables and hash values for their own.

The main risk for you is sending the user's name and password (which they may use for multiple service) in the clear, or otherwise writing your program such that it is easy to compromise an account. Securing the client's machine is really beyond your control. The server is something you can control though. The likelihood of an attack on your server infrastructure is roughly proportional to the popularity of your game/service.

Share this post


Link to post
Share on other sites
rpiller    839
OK, so I'll not worry about the client then, but just in case to add a layer of security I'll bcrypt the username/pw before encrypting and sending. That way even if someone was able to redirect the login server and change the public key to their own for encrypting on the client side the data will still be bcrypted adding that extra layer.

What kind of liability really exists for companies that require a username and pw? Clearly if stuff was leaked the company probably wouldn't survive because of losing customers but are there any legal issues around this or is that something you put in the ToC to clear yourself? Because honestly you could splash everywhere for people NOT to use a username and pw that they use for other important things, but I'm sure most people just ignore this warning.

Share this post


Link to post
Share on other sites
rip-off    10976
From what I can tell, most companies disclaim all liability they can using the EULA or TOS. However I am certainly not a lawyer so you'll have to talk to one if you want to discover what liabilities you have, which you cannot disclaim under your state/countries laws and the exact wording of such an agreement.

[quote]
Because honestly you could splash everywhere for people NOT to use a username and pw that they use for other important things, but I'm sure most people just ignore this warning.
[/quote]
But of course.

Share this post


Link to post
Share on other sites
rpiller    839
What I'm finding interesting about this is that it would seem using Asymmetric encrypting is sort of used only for the initial login AND so the client can send it's Key and IV for symmetric encryption which once the server knows those values that were randomly picked from the client, the entire conversation is now encrypted both ways so nobody would know what's up. That's interesting. In .NET it's made pretty easy. So here is some test code that I'll use for the initial Asymmetric encrypting where the client has the public key hardcoded.

[code]
class Program
{
static string pubKey = "<RSAKeyValue><Modulus>mDAvLYFX5ZFEYlMsCLeKJ61D+8XYTiqjTUrVVSKlHGWFhuxFT/AgDltT/Um2QgMnC8T6TlRam7tgCK2qbbSz+ZFJYY2a4+4rqqMdMaa7U3gF48DrpO9kyFYCRjN61tSnxrCZkFj3SVxCC7GlhpgyhKi6nLPn4HQW9FIUndSUlkk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";

static void Main(string[] args)
{
UnicodeEncoding ByteConverter = new UnicodeEncoding();

byte[] dataToEncrypt = ByteConverter.GetBytes("client username, pw, along with symmetric key & iv");

byte[] enc = Encrypt(dataToEncrypt);
string e = Convert.ToBase64String(enc);

SendToServer(e);
}

static byte[] Encrypt(byte[] data)
{
UnicodeEncoding ByteConverter = new UnicodeEncoding();
RSACryptoServiceProvider encrypt = new RSACryptoServiceProvider();
encrypt.FromXmlString(pubKey);

byte[] encryptedData = encrypt.Encrypt(data, false);

return encryptedData;
}
}
[/code]

Then on the server side it'll use the private key to decrypt the username, pw, & key/iv.

1) Bcrypt the pw to test vs what's in DB (client would also have done this when it sent)
2) If there is a match, create a RijndaelManaged object for this client using the key/iv sent by the client for this session for this client
3) Send back login success or failure using RijndaelManaged (symmetric) encryption which the client can read because they have the same key/iv
4) All communications now happen using RijndaelManaged encryption

That's pretty slick! It's pretty fun learning about this stuff :)

Share this post


Link to post
Share on other sites
rpiller    839
Actually I think I'll change this slightly.

When the client gets connected to the server the first thing it'll do is send a random key/iv for symmetric encryption via asymmetric encryption from the public key hardcoded on the client. Then the server will send back a session ID via this clients symmetric encryption, which the client will use as the salt to bcrypt their pw. Then they'll send back their username/bcrypt'd pw via their symmetric encryption and from then on all communication will be via symmetric encryption between client/server where each key/iv is unique per client.

So this way the server can give the client it's encrypted session id as the salt to add that extra layer of security. That should be good! I guess I could bcrypt all data going back and forth to if I was paranoid enough. :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this