FiloSottile / age

A simple, modern and secure encryption tool (and Go library) with small explicit keys, no config options, and UNIX-style composability.
https://age-encryption.org
BSD 3-Clause "New" or "Revised" License
17.26k stars 506 forks source link

Reconsider 20 recipients limit #139

Closed ryantm closed 3 years ago

ryantm commented 4 years ago

What were you trying to do

Trying to decrypt a file with 69 recipients.

What happened

$ age --decrypt --identity /home/ryantm/.ssh/id_rsa monit.pem
Error: too many recipients
[ Did age not do what you expected? Could an error be more useful? Tell us: https://filippo.io/age/report ]

What I expected

The file gets decrypted.

I found a part of the code where it limits the recipient number of decrypted messages to 20: https://github.com/FiloSottile/age/blob/0c650f815dde10d6e1644219b26615c5742ef743/age.go#L127

Can we expect that age will be limited to 20 recipients or is this a temporary limitation?

str4d commented 3 years ago

While I don't recall the original motivation, there does need to be a limit on the number of recipients, due to the multi-key attack on ChaCha20Poly1305 that affects age. See https://github.com/FiloSottile/age/commit/2194f6962c8bb3bca8a55f313d5b9302596b593b for more details about the attack and its mitigation.

The specific constraint is that an attacker can test 2 * LIMIT keys per encrypted file; thus doubling the recipients limit would double the speed of an attack. So we need to strike a balance between usability and effective mitigation. On that note, what use cases do you have for more than 20 recipients? For 1000? Increasing the limit (and attack speed) by two orders of magnitude would need a reasonably strong justification.

ryantm commented 3 years ago

@str4d My use case is related to agenix. I encrypt a secret that I want to deploy to a lot of servers (30) and I want to use the servers' existing SSH keypairs. I switched agenix to using Rage because it didn't have this limit.

It may be possible for me to instead encrypt the secret with only that server as the recipient, I was thinking about doing that anyway, to limit how easily a secret can be decrypted.

ryantm commented 3 years ago

Ah, it looks like the mentioned attack isn't relevant to SSH keys.

slok commented 3 years ago

Hi!

I encountered this same problem while developing Agebox.

I'll start by saying that I'm not a security expert and most probably that I'm missing something :rofl: sorry in advance:

Having this limit on the decrypt part, what could stop an attacker from downloading this source code, removing this limit, and use this to start the attack (or use Rage)? Making it configurable in the API (e.g DecryptWithOpts) and maintain the Age CLI 20 limit, would have the same security?

From the UX perspective, a person could encrypt with 21 public keys, delete the original file/data, and end with an undecryptable file. Shouldn't this error be also on the encryption part to avoid this use case?

Thanks!

ryantm commented 3 years ago

what could stop an attacker from downloading this source code, removing this limit

For example, if age is behind some service, the attacker wouldn't have direct access to the encrypted file.

secworks commented 3 years ago

How about updating the README to mention the limit? Since more than one user have been surprised it seems worth mentioning as a limit that has practical effect.

FiloSottile commented 3 years ago

Turns out I sort of underestimated how fast computers are these days.

./age -R 1000recipients.txt  0.21s user 0.01s system 98% cpu 0.215 total
./age -d -i other.txt  0.09s user 0.00s system 32% cpu 0.303 total

I'm thinking this will probably not be a problem, and if it becomes one we will understand it better and maybe have a DecryptWithOptions API already for other reasons.

(About the partition oracle attacks, we don't provide anonymity for online oracles, because there are just too many side channels, both in age and in any reasonable application that can be written with it, so having a lot of recipients doesn't cause more trouble than you're already going to have with any online oracle.)

I just removed the limit to match rage.