Most of the time, encryption is useful for sending sensitive data to recipients in a one-to-one relationship.
We have done this numerous times for clients, with subtle differences in terms of authentication and trust or encoding and error checking or digital signatures. This simple encrypt-and-send-to-recipient is great when data must be held secret between the source and target. However, what if you want to encode something so that anyone in a pre-determined list can open it? We can do this simply by encoding the secret multiple times, once for each receiver. This is acceptable both in terms of time and space if the secret is small, such as the often-portrayed-in-movies eight digit launch codes to a missile - but what if the secret is significant, like a 5 megapixel spy photograph of the enemy sleeping with the prime minister's wife?
Obviously we don't want to take a 12MB image and encode it 12 different times for 12 different people - as anyone can calculate will result in a file of about 144MB.
So how can we do this? NTFS does it. Outlook does it. But how?
Well, instead of encrypting the file with each key, let's abstract it a bit. Let's take some random data and call it a password. Let's encode the original secret with the random data (password) and then encode that random data (password) with each user's public key. Now, we only have a duplicate of the significantly smaller random data, and the 12MB secret is still safe and still only 12MB, even though we can decode it for all 12 users.
To decode, we find the random data that we can decode with our key. Then we take the decoded random data and use it as a password to decode the actual secret.
Simple!
[Edit: I am debating whether or not to put the source up for this c# stream-derived class, or roll it into a project.]