0
$\begingroup$

Requirements

We are building a system that connects multiple clients through a restful API. It allows the creation of groups of trusted clients. We need a way to store group shared data encrypted on the server side, which only the clients in that certain group can decrypt. Clients are expected to be able to join the group at any moment and still have access to the stored data.

In a more basic description let’s assume:

  • Client1 and Client2 belong to the same group.
  • Client1 wants to share data with Client2. To accomplish this, Client1 saves the encrypted data on the server, which Client2 will fetch.
  • Client1 is expected to be able to understand the data.
  • Client2 is expected to be able to understand the data.
  • The server MUST NOT understand the data
  • When a new client (Client3) joins the group he is expected to be able to understand the data.

Solution

  • All the clients in a group have a pair of public/private keys.
  • All the clients in a group have access to all the public keys of all the other clients in the group.
  • Each group will have a master key ‘K’ used to encrypt/decrypt data to be shared with the group which is initially not set.

The first client who joins the group (lets say it’s Client1) will create and store K locally and mark the group as having initialized its master key. It will then post group shared data encrypted using K and AES-128 to the API.

When Client2 joins the group the following will happen:

  • Client2 will check if the group has a master key (K) which it does, as it was created by Client1
  • Client2 will request K from any one of the group members
  • Client1 will encrypt K with Client2’s public key and send it over
  • Client2 will decrypt the key with his private key and store it locally so as to not have to request it anymore
  • Client2 will fetch the encrypted data from the server and use K to decrypt it (note that Client2 does not need to get/store all the data from the server, only the parts that it is interested in)

K is always exchanged by encrypting it using the public key of the client requesting it. This should happen at most 1 time when the client is first joining the group.

Problems

  1. if all the clients leave the group (at which moment they delete K from their local store), all the information on the server will be useless as nobody has K anymore
  2. if Client2 comes online for the first time and another group member is not online it will not be able to obtain K and will not be able to decrypt any of the data stored on the server

Am I correct when seeing these problems? And is there a solution to handle them?

I am not a expert in this domain, so your advice will be very helpful.

$\endgroup$
2
$\begingroup$
  1. if all the clients leave the group (at which moment they delete K from their local store), all the information on the server will be useless as nobody has K anymore

Yeah, that is gonna happen, and there is no way to prevent it, unless you add some trustworthy instance to the system to store such keys.

  1. if Client2 comes online for the first time and another group member is not online it will not be able to obtain K and will not be able to decrypt any of the data stored on the server

Correct. Basically this is the same as the first question, with the others just being temporarily unavailable instead of permanently.

However, there are several aspects of your current solution, which should be discussed:

  • As cygnusv pointed out in the comments: You have no mechanism to remove users. Changing the master key is necessary then, as you can't enforce deletion of anything.
  • Encrypting files with the master key... this is bad. Especially if you have to exchange the master key, this would mean that you also have to decrypt and encrypt every single file/database again. Create a fresh key for each file, table, and so on, and then put it in a list, and work with this list afterwards.
  • You have a hard requirement that the server must not know the data. Have you made sure that the server does not join the group as a dummy-server (just to get the keys)? Because your access control structure is completely missing right now. You also don't state who handles permissions, creates and publishes the keys, etc.
  • How does the invitation work? Do group members invite? Who publishes the public keys, etc....
  • What do you want to do with the data? Especially in databases this is an issue, because you can not work on encrypted data. Instead of posting SQL queries, the clients always have to request a lot of data from the DB, decrypt locally and then apply their operations locally. Almost any optimization of this gives information to the server, which he should not have.
$\endgroup$
  • $\begingroup$ Thanks for your answer. Can you please elaborate on the 'access control structure' is there a link with a good example on how this should look?. Clients joining the group have a different auth system based on one time tokens, the client must supply a token that was generated by the server in order to join a group, the token is lost after it was used. The data is stored in document database but no other querying needs to happen on it. $\endgroup$ – Calin Feb 7 '15 at 13:26
  • $\begingroup$ Also, can you think of a existing standard that will satisfy all my requirements? $\endgroup$ – Calin Feb 7 '15 at 13:33
  • $\begingroup$ Well, someone has to handle access control somehow, if you are using groups. And if that is handled by the same server as who must not know the content, you're system fails - if the server has the ability to place himself in any group, you can't prevent him from learning the group's content. About standards: no there is not really a standard for this. But access control in practice is done with so called domain controllers in windows networks, not sure about non-windows networks right now. $\endgroup$ – tylo Feb 9 '15 at 17:16
1
$\begingroup$

Your scheme does mean that the server as a passive participant can't read the data, but if your threat model includes the server trying to get access to the data you'll need to do more. tylo mentions the server (or one of its agents) attempting to join a group, but it could probably also MITM the process of another user joining the group (by returning a public key under its control).

$\endgroup$
  • $\begingroup$ Any good way to guard against MITM atack in this scenario? $\endgroup$ – Calin Feb 7 '15 at 13:32
  • $\begingroup$ There has to be some kind of authentication framework, since encrypting data is pointless unless you can verify that you're communicating with the correct person. If this is just random strangers sharing data there's no way to tell if one of them is (acting on behalf of) the server. $\endgroup$ – bmm6o Feb 9 '15 at 16:43
0
$\begingroup$

Here is an alternative method to the revocation problem. Store all objects globaly in a common area such that they are intermixed with one another. Give each object a GUID as a name that is used by the users for retrieval.

Standard GUID's give you 122 random bits so we can remove a user by simply relocating the object to a new GUID and sending that name to the remaining members.

This is hiding something in plain sight. While we have not changed the encryption key the chances of the kicked user ever being able to find the object again (if well managed by rate limiting) are low enough to call zero.

The remaining users could share the new GUID with kicked user but that's no worse then them sharing of a new encryption key under normal conditions.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.