RustCrypto / RSA

RSA implementation in pure Rust
Apache License 2.0
536 stars 146 forks source link

Minimum modulus size #445

Open ryancdotorg opened 1 month ago

ryancdotorg commented 1 month ago

RSA is catastrophically weak with 512 bit keys, and anything less than 2048 bits is insecure. A minimum key size should be enforced. Golang has proposed to require 1024 bits minimum:

https://github.com/golang/go/issues/68762

however 2048 would be a good choice where backwards compatibility requirements are minimal

tarcieri commented 1 month ago

See also: #350

dignifiedquire commented 1 month ago

For testing and supporting existing implementations I don't think a blanket limit makes sense. But maybe a default generator that limits the range would be helpful for newcomers.

ryancdotorg commented 1 month ago

Not supporting existing implementations which would require this is a benefit.

RSA 1024 and even 2048 are plenty fast for testing.

On August 9, 2024 11:00:27 PM GMT+01:00, Friedel Ziegelmayer @.***> wrote:

For testing and supporting existing implementations I don't think a blanket limit makes sense. But maybe a default generator that limits the range would be helpful for newcomers.

dignifiedquire commented 1 month ago

Not supporting existing implementations which would require this is a benefit.

I am glad for you that this is how you can run your projects, it is not the same for all of us.

str4d commented 1 month ago

I agree with @ryancdotorg and with the rationales outlined in the Go proposal.

I also note that the rsa crate already enforces limits on key sizes, specifically RsaPublicKey::new which returns an error for any key larger than 4096 bits. This method has a trapdoor for configurability via RsaPublicKey::new_with_max_size.

An intermediate pathway would therefore be to do the same thing for minimum sizes:

Then the question of whether to expose the insecure / hazmat configuration APIs at all can be separated from the "stop people shooting themselves in the foot because they think they are getting 256-bit security" issue.

ryancdotorg commented 1 month ago

For reference, here's an example of use of 512 bit RSA that could have damaged a power grid:

https://rya.nc/vpp-hack.html

It's been known to basically worthless in terms of security for decades, let it die.

pinkforest commented 1 month ago

Mis-use resistance would be good - similar with x25519-dalek we added static_secrets opt-in to track it's use.

One way would be to split the constructor for insecure and secure constructions - the insecure constructor for given bit-lengths would be hidden behind a feature - however later on how this whole thing evolves through time requiring approach to avoid breaking changes.

By having to use a feature (or cfg) to override mis-use resistance it could be potentially tracked in at least feature usage - now it is non-trivial (still possible but hard to maintain to track it's use) to find any direct dependencies which use insecure sizes - where as using a feature it can be tracked through analysing crates.io-index that exposes the used features.

When we put static_secrets feat to x25519-dalek, I found several cases of where people were using it wrong.

If we take this to extreme - there could be even a crate with all the possible keysizes as marker types and the type only gets used through feature / cfg and then features can track which keysizes are supported.

e.g. marker type could be categorised as known "minimums" with the size embedded in data-enum BITS_2048(...) :thinking:

Also according to some literature 2048 bits is considered obsolete by 2030 - should this be taken into account ? Having this evolution built in without inducing breaking changes when the inevitable factorizations happen - tick tock.

So for this reason I would say having "well known minimums" categories as types could be ok for future backward compat w/o having to do breaking changes allowing depreciation of surface that leads to insecure constructions.

teknalb commented 1 month ago

I strongly disagree with this restriction the library should remain as flexible as possible; modulus size is a user's choice. As an alternative I'd suggest informing the user with a warning or something if the key size is known to be broken.

ryancdotorg commented 1 month ago

Extensive empirical evidence shows that users of cryptographic libraries are frequently not qualified to make choices on things like modulus size.

Putting broken (< 1024 bits) and weak (< 2048 bits) behind feature flags seems like a good solution, and type annotating by size is an interesting idea.

On August 15, 2024 1:01:59 PM GMT+01:00, teknalb @.***> wrote:

I strongly disagree with this restriction the library should remain as flexible as possible; modulus size is a user's choice. As an alternative I'd suggest informing the user with a warning or something if the key size is known to be broken.

teknalb commented 1 month ago

a feature flag for broken/weak sounds good idea without sacrificing flexibility :)

tarcieri commented 1 month ago

I'll +1 @str4d's suggestion that we should follow what we already do with RsaPublicKey and have checked RsaPrivateKey APIs with short, convenient names which enforce a minimum modulus, and parallel unchecked APIs with longer names that don't enforce the restriction