6

I'm creating a huge, online mobile game. I have a few questions for you guys because my knowledge in cryptography and sending data across the network securely is kinda poor.

Some details:

  • Each user has an account
  • To log in you have to provide your username and password (through the app, not the web browser)
  • The data is transferred from the client (mobile device) to the server somewhere.

Simple! Ok so as I know, normal web authentication is secured by SSL which is just "send plain, you're safe".

On mobile I can't use SSL (even if Android provides some methods, I just can't cause I'm porting my game to iOS, using different game/networking engines etc).

I have to make the "sending & receiving" process secure so a 3rd person won't catch user's credentials.

As I read, the best way to perform this is the RSA method which uses public and private keys to encrypt/decrypt packets.

From my knowledge it works like:

  • there are two keys, private, public and a message: "message".
  • anyone can get a public key (because it's public)
  • only the server has the access to the private key
  • anyone can encrypt the "message" with the public key and it will always look the same (same msg encrypted with same public key)
  • the encrypted message can be decrypted in only one way - using a private key and it will look like the first message: "message".
  • public and private keys are not equal but they use different encrypt/decrypt algorithms so it works magically that at the end the message is the same

Please, correct me if I'm wrong!

And here are my questions:

  • Am I right in the above example, that packets sent this way (and with public key being really public) are secured (of course anything can be decrypted) but, you know, is it "secure"?
  • Should each user have its own pair of keys?
  • When should I generate a new pair of keys? With each login?
  • When should I send a public key to the user? When he clicks 'register' or 'login' (with already filled textfields with the data)? Or when he opens the app?

If there is someone that could explain these things a little bit I would be grateful! :)

Two additional questions to @Luke Park

Public key is public and you said that it shouldn't be sent over the network. Does it mean that with a public key user can decrypt the data somehow?

And the second: You said that I should bundle the public key with the application. If the public key is also a dangerous tool in a hacker's hands, is it wise to store it in code? As I know there are ways to retrieve the data from the compiled program.

And one extra! If the key is bundled (probably hardcoded) - should it always stay the same or should I ever change the pair (generate new)? As I read somewhere, by having a public key 'public' it's possible to crack the data (it takes some time, but it's possible).

Jacob
  • 212
  • 1
  • 7

1 Answers1

7

In general and with a few misunderstandings, what you said is correct. The main difference being that the ciphertext (e.g. after you encrypt the message with the public key) does not always look the same, RSA introduces some random data and padding that cause the ciphertext produced to be different, even if the plaintext is the same. This probably won't cause you any issues though, it contributes to security.

Personally, I think the effort involved to get TLS to work would be worth it over implementing your own solution. However, if you do want to do it yourself...

I wouldn't generate a new keypair for each user. A single server keypair would suffice. Distribute the public key with your application and keep the private key on your server. Use RSA not to encrypt your login data, but to negotiate an AES key, and then use that to encrypt your data. This is a basic concept used by TLS. One of the reasons this is done is because the size of the plaintext that can be encrypted by RSA is limited by the bit size of the key. Generally more than ~240 bytes cannot be encrypted without applying RSA multiple times, which is a poor idea in terms of both speed and security.

Remember to authenticate your data properly, using HMACs or an authenticated mode like GCM. Otherwise your payload could be modified (not read) in transit.

Don't send the public key to the app, it should be bundled with the app. If you send the public key over your insecure channel to the app, then nothing stops it being modified in transit. An attacker could replace it with his public key and then decrypt the traffic (and login details) with his private key.

I say again, TLS would be better and safer than implementing your own, but you seem to think this is not possible.

EDIT: I say not to send the public key over the network not because it is "dangerous" or an asset when in the wrong hands but because you are sending the public key in plaintext (e.g. over raw HTTP or TCP). Since anyone could modify this traffic (being able to see it is not a problem), they could replace the public key with their OWN public key before it reaches your app. If the key is bundled with the app already, then both parties already have their keys (e.g the app with the public and server with the private).

The public key is not useful to anyone for anything other than encrypting and verifying. It isn't something you need to hide. You just need to be able to verify that it is the correct public key. If you bundle this with your app then the security employed by the App Store and Play Store will be enough to get it to the users device with your app.

Luke Park
  • 249
  • 3
  • 8
  • I have one more question Luke. I need to generate the pair on two machines (private on the server and a public on the client). I used java algorithms to make the pair before. Can I use keys from an online generator like this one and this will work? http://travistidwell.com/jsencrypt/demo/ The reason I'm asking is that Java generates two keys in a same place so I can't generate a matching pair on two machines. – Jacob Sep 08 '16 at 19:56
  • 1
    You shouldn't generate them each time. Generate them once. Forever. Store the private and public key in two seperate files and load them as neccesary. – Luke Park Sep 08 '16 at 21:05