8

Assuming I have a server/client topology, currently I'm facing the problem that I want to generate some key on the client side and somehow make the remote server get it securely.

I'm using AES on both parts, so basically what I need is to generate a random IV and a random secret key, but how to share it with the server so it can afterward decrypt the messages?

The server side is an Apache/PHP web server, so the requests will be sent through POST, and I'll be using a SSL certificate for sure, but I'm not sure if this is enough to securely send the data to the other side.

I'd appreciate any approach/idea for this.

---- EDIT ----

This is actually an Android OS app. Instead of using direct Sockets against the server, I use HTTP POST requests from the client side to the server, and Google Cloud Messages in the opposite way simulating a multicast behavior since the server will be sending new events to the subscribed users.

But these messages will be sent just to registered users, so prior to sending one I need to register the user and thus share the key between both server and client, that's the motivation of the question.

nKn
  • 669
  • 2
  • 8
  • 14
  • It's not clear from your question why you need to encrypt the data twice (using your symmetric cypher and sending it over TLS). If you could elucidate then maybe we'd have a better chance of providing a relevant solution. – symcbean Mar 19 '14 at 12:45
  • Actually it's not requisite in my case to use TLS, I just concluded it would help for securing data from the source to the end point, but my main approach is using AES and make the server get the generated key. If this is not possible to be done securely, I'll probably try by using an assymetric method, but I'd like to know if there's some way of achieving this task with a symmetric algorithm. – nKn Mar 19 '14 at 13:17
  • 2
    That doesn't really answer my question. TLS already implements a secure symmetric key exchange mechanism. Is there a reason for wanting the server to hold both the key and the encrypted data as opposed to just the unencrypted data? – symcbean Mar 19 '14 at 13:25
  • Not really, except that in our organization we usually use AES whenever possible, I was just trying another approaches, but I'm open to any suggestion if it fits well. Probably the two algorithms together would work morelike a obfuscation approach than actually securing the data... – nKn Mar 19 '14 at 13:29
  • 1
    If that's the only reason for your requirement to implement symmetric encryption then use an AES based cipher suite in TLS/SSL and don't bother with the offline encrpyion. – symcbean Mar 19 '14 at 16:32
  • Yes, but the actual problem is that this key will be generated on the client side and has to be sent to the server for decryption, so how to send it in a reasonably secure way? – nKn Mar 19 '14 at 16:38
  • 2
    TLS automatically generates a key on the client side, securely sends it to the server, then uses it to encrypt the rest of your session. Sounds to me TLS does all you need, and certainly the norm is to just leave things to TLS. If your management say "use AES" that is fine - you can use AES with TLS. If you want further advice then you'll have to explain more about the specifics of your application. – paj28 Mar 20 '14 at 20:33
  • Is this a web app, I think we need a better understanding of how the client will connect to the server. The current answers are generic key exchange citations, but if you walk us through more of the process you will get more focused answers. – Eric G Mar 23 '14 at 19:50
  • @EricG this is actually an Android OS app. Instead of using direct `Socket`s against the server, I use `HTTP POST` requests from the client side to the server, and `Google Cloud Messages` in the opposite way simulating a multicast behavior since the server will be sending new events to the subscribed users. But these messages will be sent just to registered users, so prior to sending one I need to register the user and thus share the key between both server and client, that's the motivation of the question. – nKn Mar 23 '14 at 20:25
  • Please update/edit and put this information in your question. Please provide as much as possible to get the best solution. – Eric G Mar 23 '14 at 23:26

5 Answers5

7

What you are looking for is a public/private key pair otherwise known as SSL in the computer world.

An SSL certificate as you mentioned is enough security since to find out what is being sent you need the private key of the certificate and you cant get that without breaking into the server.

If you don't want to use SSL another option would be to use a hardcoded public/private key pair into the client/server which would act just like SSL but without having a signed certificate.

user36976
  • 3,233
  • 4
  • 14
  • 22
  • 1
    SSL/TLS definitely seems like the right answer. Additional steps needed afterward though if the webserver side is then trying to verify whom it's talking to over SSL. OP will need to do this before POSTING sensitive data (though logging into an account should suffice?). – pacifist Mar 20 '14 at 21:29
6

If the question is understood properly, what is really asked here is how to do a key-exchange.

Having implemented this in the same manner discussed for a security product, the following general approach works independent of the underlying transport protocol (and further does not make any assumptions about its underlying security):

  1. Client generates a (random) transaction key using some (presumed) good IV and strong pseudo-random algorithm suitable for AES256 (or better) encryption.

  2. Client generates a (new random) symmetric response-key using same process as in step (1).

  3. Client encrypts the response-key (2) with the transaction key from (1) ... using AES256 or whatever preferred algorithm.

  4. Via PKI, the client asymmetrically-encrypts the transaction key (1) for the server (recipient) using Server public-key. This will ensure only the Server can read the transaction key (1).

  5. Generate a payload in which the client (sender) is identified, associated with their public-key on the server (receiver) side. In this payload will be the (PKI encrypted) transaction key (1) and the (AES encrypted) response-key (2). There is more to this such as hashing contents to ensure non-repudiation, etc - but let's focus on the key exchange...

  6. Client sends the payload to the Server. It is recommended this be done via TLS, etc but this is not strictly necessary as the encryption is sufficient to protect the keys. However, being sure the client is sending the payload to the [right] server (receiver) without eavesdropping improves the security of the key-exchange.

  7. Via PKI, (using Server private-key), decrypts the first part of the payload: the transaction key.

  8. Using the transaction key, the response-key is decrypted using AES256 (must be same algorithm and IV as used for response-key encryption - should be part of payload).

  9. At this point, the client waits for a response from the Server.

  10. Server, using the response-key that the Client knows (he generated it) for this transaction, can then encrypt any content bound for the Client simply using AES256 (some symmetric algorithm).

  11. Client uses symmetric algorithm and response-key to decrypt Server response.

Provided the PKI secret-keys are not compromised, good salts, IVs, etc are used... this process is very solid (used by security organizations around the world).

Note that ANY cryptography can be broken EVENTUALLY. Using this transaction-based process with new (randomness of key is important) (large) pseudo-random keys for each request/response pair, it very difficult to compromise the conversation.

Using this method, even if ONE transaction-key is compromised, it very much limits the exposure since access would only be gained to a single transaction at a time.

Darrell Teague
  • 454
  • 3
  • 6
  • There are a couple of things I don't understand; in step 4, wouldn't the client would need to encrypt the transaction-key with the Server public-key? He could also potentially sign it with his own private key. Then in step 7, what is the purpose of looking up the public-key, unless it is to validate the client signature, before decrypting with the server-private key? Finally, what is the advantage of the transaction key at all in this exchange? Why not simply use PKI to encrypt the response key and only use the response key? How does the transaction key help make it a more secure exchange? – Eric B. Feb 24 '18 at 03:52
  • Yes in PKI the client (sender) encrypts the key (data less than about 114 bytes per then-current RSA limitations on data size) using the sender public key, thus making it only visible to them. – Darrell Teague Mar 05 '18 at 18:15
  • Yes, the public key lookup is for signature validation. – Darrell Teague Mar 05 '18 at 18:16
  • The symmetric key is needed for the payload (such as when using AES256 et al). RSA has a limitation of about 114 bytes as the maximum data length and it is MUCH SLOWER than any symmetric protocol. Hence the hybrid encryption scheme. Lastly, having a per-transaction key limits the damage from a bad actor obtaining a given transaction and thus only having access to that data. Of course, if the attacker has access to the data stream and impersonates the receiver (networking, has their private key, etc) ... then all comms are compromised. – Darrell Teague Mar 05 '18 at 18:18
  • HI Darrel, I was wondering if this approach has been formalized somewhere? – DaWNFoRCe Mar 27 '20 at 10:10
  • None that I've seen but then again there is so much good material by so so many authors. Perhaps that implies I need to finally write a book. Then it would be formalized. :-) – Darrell Teague Mar 28 '20 at 16:40
  • Thanks for this well-written answer. What I don't understand is the need for the response key (RK) in addition to the transaction key (TK). Obviously if the TK is compromised, so is the RK, because the former is used to encrypt the latter. If the server's private key is compromised, TK (and thus RK) can be decrypted as well. So the only scenario this protects against is a compromise of the RK alone (through guessing?). This would allow eavesdropping on the response and spoofing a response. What would the fact that the TK isn't compromised buy us in this scenario? – misberner Nov 20 '20 at 23:41
  • The response key is to allow for efficiency such that the caller can now just create an AES (symmetric type) response using said key and the server can quickly decrypt it. This is both secure and provides caller verification since they should be the only party that knows this random key. The txn id acts as a verifiable nonce to prevent against replay. – Darrell Teague Nov 22 '20 at 21:58
  • In general as to compromise of any RSA key - well, that's really the fox in the hen house situation. Suffice to say that once a master-key is 'owned' by a bad actor, much like owning a server where the veracity of the software itself is now compromised - represents a complete breakdown of the security apparatus in any scheme. – Darrell Teague Nov 23 '20 at 17:18
  • There is now a somewhat formalized implementation of this approach in the newly released service Private Speak: https://www.privatespeak.com – Darrell Teague Dec 30 '20 at 22:22
4

Secure Sockets Layer (SSL) seems to be the answer you are looking for. Here's a quote from the Wikipedia page:

They use X.509 certificates and hence asymmetric cryptography to assure the counterparty with whom they are communicating, and to exchange a symmetric key. This session key is then used to encrypt data flowing between the parties. This allows for data/message confidentiality, and message authentication codes for message integrity and as a by-product, message authentication.

Also though, you might just want to have a look at RSA and Diffie-Hellman algorithms which can be used in a client/server model to exchange keys securely. They however, have many types of attacks attached to them; the man-in-middle is one of them, in which an intruder might just step in and steal the key. Another attack possible is the brute-force, in which an intruder might guess the key you are trying to transfer.

If you want to exchange keys securely using these algorithms, make sure you hash them using the MD-5 or SHA-X algorithms. You can even encrypt them if you have space, using DES/Double DES/Triple DES, or AES-128/192/256 encryption algorithms.

Read through this:

Before a client and server can begin to exchange information protected by TLS, they must securely exchange or agree upon an encryption key and a cipher to use when encrypting data. Among the methods used for key exchange/agreement are: public and private keys generated with RSA (denoted TLS_RSA in the TLS handshake protocol), Diffie-Hellman (denoted TLS_DH in the TLS handshake protocol), ephemeral Diffie-Hellman (denoted TLS_DHE in the handshake protocol), Elliptic Curve Diffie-Hellman (denoted TLS_ECDH), ephemeral Elliptic Curve Diffie-Hellman (TLS_ECDHE), anonymous Diffie-Hellman (TLS_DH_anon), and PSK (TLS_PSK). The TLS_DH_anon key agreement method does not authenticate the server or the user and hence is rarely used. Only TLS_DHE and TLS_ECDHE provide forward secrecy. Public key certificates used during exchange/agreement also vary in the size of the public/private encryption keys used during the exchange and hence the robustness of the security provided. In July 2013, Google announced that it would no longer use 1024 bit public keys and would switch instead to 2048 bit keys to increase the security of the TLS encryption it provides to its users.

Ayush Khemka
  • 81
  • 1
  • 2
  • 5
3

Both answers have identified SSL/TLS, but consider adding client authentication to the mix. This will guarantee that the server will only accept connections for authenticated / known clients. The drawback with this is that:

  • a) Each client must be issued with its own client authentication certificate (although not necessarily from the same CA as the server).
  • b) Each client must store the matching private key. This will probably be in software (although it can be stored on a smartcard or PKI USB token).
  • c) Each client must be registered with the server, although this may differ based server implementation. Some servers may allow trust based upon known root CA certificates. Some servers may accept certificates based on a white-list approach. Some may be a blend of both or alternatives.

The server should be able to be configured to accept client-authenticated connections only. In some web servers this setting can be applied to individual resources on the server.

Look at the Wikipedia page for details of the client authenticated TLS handshake:

TLS Client Authentication

NRCocker
  • 483
  • 2
  • 6
  • Actually it might not be necessary that each client have its own certificate. You can build a fixed private key and its associated certificate into the application, and that's sufficient for the server to be able to authenticate that a registration request is coming from a copy of the client (or that someone has reverse engineered the client). Depending on your registration scheme, you may be able to use that to bootstrap per-client certificates. – armb Mar 26 '14 at 15:39
  • For using standard per user CA signed client certificates, see http://developer.android.com/training/articles/security-ssl.html#ClientCert http://nelenkov.blogspot.co.uk/2011/11/using-ics-keychain-api.html – armb Mar 26 '14 at 15:41
  • Having a cert for client is right answer. Following my original post, where the asym encrypted key is sent to server, one would add a step to digitally sign a hash of the payload with the Client private key. The Server would need the Client public key registered in advance as trusted but this step would both verify the Client AND provide verification that the payload was not bit-fiddled. – Darrell Teague Mar 28 '20 at 17:05
0

I'm simplifying Darrell Teague's answer, and also correcting some points (specially 7 and 4), this should also answer Eric B. Questions.

  1. The Client generates a (random) shared key using some (presumed) good IV and strong pseudo-random algorithm suitable for symmetric encryption (e.g. AES).

  2. The Client generates a payload in which the Client (sender) is identified, associated with its public-key on the server (receiver) side. This payload will also include the (PKI encrypted) shared key (1).

  3. Via PKI, the client asymmetrically-encrypts the payload for the server (recipient) using the Server's public-key. This will ensure only the intended recipient (the Server, who knows the Server's private key) can read the payload containing the shared key (1).

  4. The Client sends the payload to the Server.

  5. Via PKI, using the Server's private-key, the Server decrypts the payload containing the Client identification data and the shared key (1). Now the both the Client and the Server know the shared key.

  6. At this point, the Client and the Server can both use the shared key for further communication.

  7. At some point the session is over and the shared key is disposed. Every session requires a new shared key.

hawk78
  • 1
  • 1
  • The OP question was effectively how to do a key exchange.There is no session implied. Further, answer describes solution as being effective within txn scope. This solution exposes all transactions executed using the one generated shared key. There had been an implied use of digital signatures for client authentication... which was used with a banking client. This may have caused some confusion and was simplified in an edit to the post. – Darrell Teague Mar 28 '20 at 16:52