Suppose I have a server which is publishing information (e.g. via a message bus) to four parties: A, B, C and D. All traffic can be discovered in encrypted form by any party. In order to make use of the information, obviously it would need to be decrypted:
- Party A should be able to read all information (i.e. decrypt information intended for A, B and C)
- Party B should be able to read information intended for B and C
- Party C should only be able to read information intended for party C
- Party D should be able to read information for B and D
Obviously this could be achieved by having completely separate public/private key pairs for each party and then sharing the private keys as per the requirements above. Unfortunately this does not scale nicely to hundreds of parties.
Is there a better way?
EDIT
Basically, what I would like to do is for each person to have their private key and for me to say, when encrypting a message, that it is encrypted with key = A | B | C such that this means that a person with any of key A, B or C can decrypt it. Imagine a trunk which can have n locks fitted to it, any of which can open the trunk.
What you want can be achieved using normal protocols based on public key cryptography. The Bouncy Castle Crypto APIs has support for both OpenPGP and CMS, either of which can work from Scala.
TO set everything up:
The protocols allow encryption using multiple public keys. For example, if you use something like the PGPEncryptedDataGenerator, then you would call the addMethod(PGPPublicKey) method for every recipient you wish to be able to decrypt the message.
There are a lot of nuances to the API’s, but the unit tests and examples will really help you navigate them.
Implementation Details
Both protocols work in fundamentally the same way.
Recipients reverse the process to decrypt the message