I'm creating a file sharing system, in which the unique key of a file is one of the critical components to the retrieval of that file. For simplicity, lets say the unique keys are the file names. I'd like to keep these filenames secret, and make them available only to the owner of the files and to other users with access to it.
This is how I designed my solution:
User U1 has a masker key CMK1 stored in a KMS. He also has files with names F1, F2 and F3. I'd like to keep these filenames a secret. To hide their names, user U1 creates keys K1, K2 and K3, encrypts them with CMK1 and saves them in a database as CMK1(K1), CMK1(K2) and CMK1(K3). The file names are saved in a separate database as K1(F1), K2(F2), K3(F3).
At this point all of K1, K2, K3 and F1, F2, F3 are never saved as plaintext, and CMK1 is safe inside the KMS.
When user U1 wants to share file name F1 with user U2, he gives him K1. User U2 saves it as CMK2(K1), and now has access to K1(F1) in the database. He does not have access to K2(F2) and K3(F3).
Now, the keys and filenames are still encrypted and U2 knows the name of F1.
However, this creates an issue of scale - at the best case (no one share anything) I'll have to keep as many as #Users + #Files
keys and as many as #Files
database entries. At the worse case (all the users share all of their files with everyone), I'll have to keep the same amount of keys and much as #Users * #Files
database entries.
Is there a more efficient way to design this?
Is there a better approach to this altogether?