Skip to content

Minimum modulus size #445

Description

@ryancdotorg

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:

golang/go#68762

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

Activity

  1. tarcieri commented on Aug 9, 2024

    @tarcieri
    Member

    See also: #350

  2. dignifiedquire commented on Aug 9, 2024

    @dignifiedquire
    Member

    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.

  3. ryancdotorg commented on Aug 9, 2024

    @ryancdotorg
    Author
  4. dignifiedquire commented on Aug 9, 2024

    @dignifiedquire
    Member

    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.

  5. str4d commented on Aug 9, 2024

    @str4d
    Contributor

    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:

    • Have the default pathway enforce a secure minimum size in RsaPrivateKey::new and RsaPublicKey::new, which we can increase as necessary in line with best practices.
    • Have a trapdoor for configurability via e.g. RsaPrivateKey::new_with_insecure_key_size, which enables reviewers to clearly identify codepaths that are insecure in production.

    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.

  6. ryancdotorg commented on Aug 10, 2024

    @ryancdotorg
    Author

    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.

  7. pinkforest commented on Aug 11, 2024

    @pinkforest
    Contributor

    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(...) 🤔

    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.

  8. teknalb commented on Aug 15, 2024

    @teknalb

    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.

  9. ryancdotorg commented on Aug 15, 2024

    @ryancdotorg
    Author
  10. teknalb commented on Aug 15, 2024

    @teknalb

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

  11. tarcieri commented on Aug 15, 2024

    @tarcieri
    Member

    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

  12. elichai commented on May 7, 2025

    @elichai

    @tarcieri Is there any way to do this without adding to this as a fully fledged feature? Maybe some kind of fn modulus_size(&self) -> usize that will allow us to check that key.modulus_size() >= 3072?

    EDIT: It is possible via the PublicKeyParts trait, like so: key.n().bits()

  13. tarcieri commented on Jun 4, 2025

    @tarcieri
    Member

    I made an attempt at this in #526 but it's breaking the majority of current tests

  14. pinkforest commented on Aug 22, 2025

    @pinkforest
    Contributor

    Fixed them in #561 (by increasing key sizes)

    All tests complete in 5 mins now so pretty much the ~same :)

    Units are all 1024/2048 with no difference in speed

    However proptests are gated under feature=hazmat now using RSAPrivateKey::new_unchecked w/ 512bit key to save our CI

  15. tarcieri commented on Sep 4, 2025

    @tarcieri
    Member

    Merged #526 but ran into some test failures so I reverted.

    I think a more incremental approach than #526, that first starts with placing limits on keygen, and then applies the limits generally to any loaded key (with escape hatches) might be in order.

  16. added a commit that references this issue on Sep 21, 2025
    77d9996
  17. added 2 commits that reference this issue on Jan 27, 2026
    6f7cee3
    f31e817
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions