How can data be encrypted in a client-server application so only clients can read it? 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


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
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.
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.


  
  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.