I would like to share documents within groups and make sure that the member of each group can only access the documents shared in his/her group. I also want to make sure that non of the parties can cheat in the process of creating this architecture.
Situation:
There are 5 participants (A, B, C, D). There are two groups (blue: A, B, D, red: D, C). A and B can only see blue documents (like Document_1) and C can only see red documents (like Document_2). D can see documents shared in both groups.
Approach: The following approach is close to the approach in Tom Leeks answer and is close to OpenPGP. This approach is taken, because it scales to groups with many users.
Example for blue group:
- A generates a key pair. Public key: pk_a. Private/secret key: sk_a
- B generates key pair pk_b, sk_b
- C generates key pair pk_c, sk_c
- pk_a, pk_b, pk_c are posted to a key server, visible to the public
- A (or any member of the blue group) generates a symmetric key s1
- A calculates pk_b(s1) (s1 encrypted with pk_b) and pk_c(s1).
- A posts pk_b(s1) and pk_c(s1) to the server
- B and C can now take those values and decrypt them using theis sk
- A, B, C now know S1 and can share data within the blue group
- If they are posting data in the blue group, they can use their sk to indicate to the others that it was really send by them
- we do the same for the red group with the symmetric key S2
Problem: How can we make sure that A actually send the correct symmetric key? A might want to exclude B and send pk_b(Sx) instead of pk_b(S1). B would be excluded of the communication.
Idea:
- A is posting a random integer "to B" sk_a(pk_b(int)). To authenticate himself, he is encrypting it with his secret key
- B takes that value increments it and posts it to C sk_b(pk_d(int + 1))
- D is posting sk_d(pk_a(int + 2))
- A can confirm that things are correct and that he indeed received his original integer, incremented by 2
- A posts sk_a(pk_b(int + 3))
- B can confirm that things are correct
- B posts sk_b(pk_d(int + 4))
- D can confirm that things are correct
Does this approach make sense? Is there a more elegant or efficient solution?