Jump to content

  • Log In with Google      Sign In   
  • Create Account

Beginner Packet Encryption


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
18 replies to this topic

#1 Carradine   Members   -  Reputation: 260

Like
0Likes
Like

Posted 26 April 2013 - 05:30 PM

I hope I am not bringing up a question that is already answered, if it has, a point in the right direction would be appreciated, but in all my searching I can't seem to find my exact answer to my question.

 

I have fully functioning MMO with client/server communication.  Players download the client obviously, and the server is located remotely (currently controlled only by me) an an Amazon AWS server.

 

So my basic is question is this.  Players create their account for my game from within the client (email, username, password, etc), store this on the server (currently encrypted on the client using a simple XOR encryption, then sent to the server ).  And now of course I am looking to now finally make this packet encryption more legitimate and professional.

 

While researching this, I find people asking similar questions, but I see them jumping right into terms like already having "SSL encryption", sending "salts" and "hashing" the data, but I need to know where to begin from step 1.  I am not finding a step-by-step general procedure for beginning to encrypt packets, and figuring out which method I should be doing.  It seems like this is more complicated than just writing some simple algorithms and hashing data.

 

I am attempting to make my game secure enough so that if I do start charging money for the game, or just make the game go "live", I can tell my players "Your login information is secure".  I am not interested in dealing with any real money account information at this point.  Just one step at a time.

 

I am basically looking for a guideline of where to start with this.  The simplest answer is basically what I am looking for.  My game is currently communicating with Winsock, and for now is going to be windows platform specific.  Coded in C++.

 

Should I just look into using something like OpenSSL and go from there?


Edited by Carradine, 26 April 2013 - 05:31 PM.

--------------------------Vantage - 2006, 2008, 2009 Independent Games Festival Submission http://www.crystaldragon.com

Sponsor:

#2 frob   Moderators   -  Reputation: 21297

Like
0Likes
Like

Posted 27 April 2013 - 07:09 PM

Basically, yes, you have the right idea.  Use Transport Layer Security (TLS) because it doesn't really interfere with the rest of the network program.

 

The salt and XOR during transmission isn't really useful.  You need to just encrypt your communication.  This will ensure that when a player connects to your server nobody can intercept or modify the content.

 

 

If you already have your app with WinSock, you can use the WSASetSocketSecurity() function.  It will either require that a secure connection is established or fail to connect.

 

You might also consider using SChannel, which is Microsoft's implementation of the wrapper.  Here's an example where it is used in practice.  It is a little more complex but it also gives more control than the simple success/fail model.


Check out my personal indie blog at bryanwagstaff.com.

#3 Carradine   Members   -  Reputation: 260

Like
0Likes
Like

Posted 28 April 2013 - 11:28 AM

Those sound like the solutions I may be looking for, I will begin researching those immediately, thanks for the reply!


--------------------------Vantage - 2006, 2008, 2009 Independent Games Festival Submission http://www.crystaldragon.com

#4 hplus0603   Moderators   -  Reputation: 5303

Like
0Likes
Like

Posted 28 April 2013 - 07:15 PM

Before you spend too much time on this: What particular kind of attack are you trying to guard against?

Chances are that changing from your plain TCP connection to TLS at this point in your game development is largely a waste of time, because the real problem you're having is likely getting enough people to think the game is fun that they come back and play again :-)
enum Bool { True, False, FileNotFound };

#5 Dave Weinstein   Members   -  Reputation: 505

Like
3Likes
Like

Posted 28 April 2013 - 10:54 PM

So, XOR is meaningless. Really, seriously, honestly, you might as well ROT-13 it, meaningless.

 

Here are some basics on cryptography for data-at-rest.


One, don't write your own. Just don't go there. Get a tested library, use that.

 

Two, in an ideal world, you want to be able to swap out your crypto algorithm if a problem arises in it. So your code shouldn't be deeply tied to the cryptographic routine you are using. This is generally termed "crypto-agility".

 

Three, salts and hashes. So, a cryptographic hash is a one way conversion. You take a value (say, a password), and you generate a hash of it. In order to get the original from the hash, you would have to just generate values until you got one that matched the same hash (more on this later). You then store the hash in your database (so you never keep the actual plaintext of the password in your database). A salt is a value that you derive deterministically from the account (whether it is intrinsic to the account or simply a random value stored with the account) that you add to the password before hashing it. What this does is mean that if Bob has password "123456" and Alice also has password "123456", they still have different hashes in your database. Otherwise, if I hash "123456", I can immediately get every account that used that password. On the other hand, if I get your database, and I want to get Bob's password only, it doesn't make a difference.

 

Which brings us to four, hashes continued. Counter-intuitively, you want to use *slow* algorithms for hashing when you are picking your algorithm. The reason for this is that you can afford the extra time to hash a password on login, but you make it much harder for someone to brute force things. Remember how we said you'd have to algorithmically generate strings until we got our hash again? That's why you want a slow algorithm (ex. bcrypt).

 

Now most of what I just said only applies to the password.


Storing other information is also important, and can have real legal repercussions depending on where the servers are located (for example, if you were suddenly running on a server in the EU, you fall into EU privacy laws), and if you start dealing with Credit Cards you have all sorts of contractual headaches about data storage. The easiest way to secure data is not to have it, so always consider whether or not you need a piece of information at all.

 

If you are storing it, consider what parts of your server actually need it, and when, and keep the data encrypted at rest. You may want to have the service that actually needs that information on a separate server (one that doesn't handle the untrusted input that is user interactions on a regular basis), such that even if someone were able to get control of the game server, they wouldn't be able to pivot to get the user information.

 

And finally, I am not a cryptographer. It is entirely possible that I made an error, especially since I'm just jotting this post off, and I'm certainly not a lawyer.


Edited by Dave Weinstein, 29 April 2013 - 07:00 AM.


#6 Carradine   Members   -  Reputation: 260

Like
0Likes
Like

Posted 29 April 2013 - 11:58 AM

Thanks for all the information, that is all extremely useful.  I am currently running all my information through TCP.  I do not know what the difference between using TCP and TLS until I start looking into this more, however I am only planning on trying to sending only account information this way (email, login, password) so I am only going to send a few packets securely for now.

 

I am not going to attempt to do any type of monetary transactions of any kind (credit cards, virtual goods/cash etc ).  If I get to that point I will rely on a third party, but I am not near that stage just yet.  However I may want people to receive a "CD-key" to register their game (free or paid) off a website login at some point which they would enter as well, but will be the extent of how far I go with this until I rely on more professionally secure methods for money transactions.

 

As I mentioned before I would just like to assure people who play game that their information is "secure" when they send it and it is stored on the server.  I realize it can never be 100% foolproof.  But again, its better then what I am doing now.

 

I am not trying to guard against any particular type of attack, just trying to do a general secure encryption for this information.


--------------------------Vantage - 2006, 2008, 2009 Independent Games Festival Submission http://www.crystaldragon.com

#7 Carradine   Members   -  Reputation: 260

Like
0Likes
Like

Posted 29 April 2013 - 02:11 PM

I found this great post on Stack Overflow which seems to describe what I should be doing based off of your suggestions as well:

http://stackoverflow.com/questions/5415752/how-to-save-string-username-password-in-encrypted-form-in-database-and-decryp

 

It explains that you should salt and hash the password using the SHA-256 algorithm from OpenSSL.

 

But a few questions still linger.

 

How should I still send the password (and other info like login/email) to the server by itself so I can still salt/hash it?  Should just still be sending it through WSASetSocketSecurity() be safe enough since I will be salt/hashing it on server and not storing the password in any way on the server? (Should I be masking the data somehow to deter packet sniffers? etc..)

 

Does WSASetSocketSecurity() have any performance issues?  Should I just leave it on for the player the whole game?  Or just use it when sending sensitive information packets?

 

I hope I am thinking about this the right way.  Of all my years programming I just seem to have a bit of trouble wrapping my head around this.


Edited by Carradine, 29 April 2013 - 02:16 PM.

--------------------------Vantage - 2006, 2008, 2009 Independent Games Festival Submission http://www.crystaldragon.com

#8 ApochPiQ   Moderators   -  Reputation: 15703

Like
0Likes
Like

Posted 29 April 2013 - 03:07 PM

Don't transmit password data directly if you can avoid it. Use a method like SRP to handshake instead.

#9 Carradine   Members   -  Reputation: 260

Like
0Likes
Like

Posted 29 April 2013 - 06:06 PM

Okay so this is what I am thinking so far...

 

I will open up my TCP socket and add  WSASetSocketSecurity to it.

I will implement a self-made SRP Protocol to the character string.

I will use the SHA-256 hash algorithm from OpenSSL for the SRP hash

 

The SRP pseudocode from wikipedia makes it seem simple enough to implement by hand.

 

I really don't know the stability, uses, or performance issues of doing this.  The documentation for those issues seem non-existant.  I am assuming this will provide "enough" protection for account information, without completely converting my code from TCP to TLS.

 

Any thoughts?


--------------------------Vantage - 2006, 2008, 2009 Independent Games Festival Submission http://www.crystaldragon.com

#10 hplus0603   Moderators   -  Reputation: 5303

Like
0Likes
Like

Posted 30 April 2013 - 09:40 AM

Before you spend too much time on this: What particular kind of attack are you trying to guard against?
enum Bool { True, False, FileNotFound };

#11 Carradine   Members   -  Reputation: 260

Like
0Likes
Like

Posted 30 April 2013 - 10:18 AM

I am not trying to guard against any particular type of attack, I just want to have some general security measures for account information protection (login/password/CD-Key) that are being sent across the client and server.  

 

I am attempting to implement  WSASetSocketSecurity but I am having a difficult time of it due to a lack of documentation and examples.  I apparently have the security settings enabled, the client connects to local computer on the same system, but when I connect to remote server it fails to connect.

 

I must admit I don't even know if I am going in the right direction with this.  It almost literally like seems one step forward two steps back.  If I cannot get this security socket protocol working I may just proceed with the salt/hashing algorithms on a non-secure socket and just call it there.  


--------------------------Vantage - 2006, 2008, 2009 Independent Games Festival Submission http://www.crystaldragon.com

#12 Carradine   Members   -  Reputation: 260

Like
0Likes
Like

Posted 30 April 2013 - 04:18 PM

Okay, so after much more research and running into brick walls I have come up with the solution of just holding off on upgrading to secure sockets, and just focus on the packet hash and encryption for now.  Based on what I have read and researched, this seems to be the simplest answer for me until I really want to go full speed into securing sockets for money transfers,etc (which I am currently not doing nor interested in at this time).

 

So for my account protection I do this:

 

For Account creation:

1. Player enters email,login,password on the client

2. Send only the login name to the server

3. The server creates the required information for the account, including a salt, and a time-based mask string (to prevent replay attacks)

4. Server sends the salt, and the mask to the client

5. Client adds the salt to the password string

6. Client performs a SHA256 hash on the new string using the OpenSSL SHA256 function.

7. Client applies the time-based mask to the hash

8. Client sends all the account information (login,email,hash) email is masked as well for posterity

9. Server de-masks the information and places it into the account database

 

A similar method is used for the login process as well.

 

Any suggestions for what to improve on this are appreciated.  And again thanks for all the replies, it was all helpful.


--------------------------Vantage - 2006, 2008, 2009 Independent Games Festival Submission http://www.crystaldragon.com

#13 hplus0603   Moderators   -  Reputation: 5303

Like
0Likes
Like

Posted 01 May 2013 - 12:34 PM

"holding off on secure sockets" is the wrong solution.

There are two levels of security:

1) You don't really care if a determined man in the middle can read the data. Such a man in the middle must have access to the wires to snoop on the network (or an open wireless network.) At this point, XOR encryption, or no encryption, or your own cryptosystem based on hashes, is approximately the same level of security. Spending any time on this is time you don't have to spend on more important things, so don't do it.

2) You care about determined men in the middle (the most common being open wireless network sniffers.) At this point, you use TLS. If you can't get the Microsoft TLS wrapper to work, then use a library like openssl or whatever.

Note that, to guard against men in the middle, you have to also do remote host authentication, which requires you to get a SSL certificate. You can create a self-signed certificate, and provide the public part of that with your installed client, if you don't want to pay for a "real" SSL certificate.

(I'm sloppily using "SSL" and "TLS" interchangeably above, whereas you really should be using TLS for everything these days.)

Edited by hplus0603, 01 May 2013 - 05:28 PM.

enum Bool { True, False, FileNotFound };

#14 Kylotan   Moderators   -  Reputation: 3338

Like
0Likes
Like

Posted 01 May 2013 - 06:34 PM

4. Server sends the salt, and the mask to the client

5. Client adds the salt to the password string

6. Client performs a SHA256 hash on the new string using the OpenSSL SHA256 function.

7. Client applies the time-based mask to the hash

8. Client sends all the account information (login,email,hash) email is masked as well for posterity

9. Server de-masks the information and places it into the account database

 

By 'time-based mask' you mean 'trivial encryption using the current time as a key', right?

 

A hacker with access to the client will quickly crack the mask system, and they will be able to grab access to the salt as well. With that information, cracking an individual password is often trivial.

 

If you use this system, don't let people choose their own passwords. Instead, generate one for them. That way, if the system gets compromised, they don't lose the password that they use for Gmail, online banking, etc.

 

Personally I like to handle my logins via a tiny web server which hands out login tokens. The webserver can operate over HTTPS so the password submission is pretty secure and the login token is signed with a hash that includes a secret key, making it impractical to spoof.

 

I don't think you need to worry about encrypting regular MMO traffic. I don't think most MMOs bother. Just ensure the important stuff goes via your secure channel, whatever that is.



#15 Carradine   Members   -  Reputation: 260

Like
0Likes
Like

Posted 02 May 2013 - 08:51 PM

Well it was a monsterous effort for me, but I decided to take your suggestions and I have integrated OpenSSL into my code and I have implemented Secure Sockets.  I even got it working with non-blocking sockets (so far I had no problems with it, but research tells me its a complicated issue to implement non-blocking sockets with OpenSSL but, knock on wood).

 

I searched a huge amount of sites trying to get this all implemented, but for those who are in the same boat as I am, these websites were the most helpful:

 

http://simplestcodings.blogspot.com/2010/08/secure-server-client-using-openssl-in-c.html - A great set of code to test secure socket openSSL connection, even tell you how to make your own certificates.

 

http://slproweb.com/products/Win32OpenSSL.html - a Win32 C++ version of the OpenSSL source with libs ready to go.

 

So hopefully with this implemented and the previous methods for password protection I have a decent basis of network security, and I have OpenSSL all ready to go if I need to continue along this path.

 

I am assuming my self-made certificate will be acceptable for now since I am still in the testing phases of my game.

 

The worst part of this process was the lack of documentation and examples I was running into.  Some examples even looked completely foreign from others, where they almost looked like another API.

 

Again I am appreciating all this advice from you all.  I hope I am done posting any major questions about this, but who knows :)


--------------------------Vantage - 2006, 2008, 2009 Independent Games Festival Submission http://www.crystaldragon.com

#16 hplus0603   Moderators   -  Reputation: 5303

Like
0Likes
Like

Posted 03 May 2013 - 11:33 AM

I decided to take your suggestions and I have integrated OpenSSL

Great!

I am assuming my self-made certificate will be acceptable for now

As long as you control the game client, so you can provide your own root certificate to the client, it will be good enough for production, too.
enum Bool { True, False, FileNotFound };

#17 Carradine   Members   -  Reputation: 260

Like
0Likes
Like

Posted 03 May 2013 - 08:51 PM

I hopefully have one final question regarding this.  Now that I have the secure connection to pass account information back and forth, I want to remove that secure connection afterwards so I can use an unsecure socket for the game packets since none of the data that will be sent will be of any compromising value (I am assuming that using an unsecure socket is much faster to send the data).  

 

Would I be able to open two sockets on the client, one Secure and one non-secure, then when the secure socket authorizes the login, It sends a unique key to the client for the unsecure socket to connect to the server to initialize the unsecure socket?

 

I am afraid that I may do something that would compromise all the security I just implemented in some way.

 

UPDATE: What I am going to plan to do is have the client connect with two sockets on two different ports, one secure, one normal.  I will compare the IP address of the two incoming sockets and "link" them together on the server.  Once the authentications are done, I will stop the secure socket, and only use the normal unsecure socket for the game.  If there is any other way to accomplish this I would appreciate any ideas.  Again, I searched for many hours about this and found no answer for this.  I feel I am missing something simple here but I cant seem to put my finger on it.


Edited by Carradine, 04 May 2013 - 01:20 AM.

--------------------------Vantage - 2006, 2008, 2009 Independent Games Festival Submission http://www.crystaldragon.com

#18 ApochPiQ   Moderators   -  Reputation: 15703

Like
0Likes
Like

Posted 04 May 2013 - 11:47 PM

Generally speaking, network latency is going to dwarf any time spent on encryption/decryption of the actual packet stream. It is entirely possible to have a realtime network simulation using encrypted traffic.

#19 hplus0603   Moderators   -  Reputation: 5303

Like
0Likes
Like

Posted 05 May 2013 - 10:18 PM

I am assuming that using an unsecure socket is much faster to send the data

In 1995, that might have been the case.

These days, not so much. CPUs are very fast, and wires are very, very, slow by comparison. I'd just keep using the secure socket.
enum Bool { True, False, FileNotFound };




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