Problem/Motivation

RSA SSH keys remain widely used, but keys below 2048 bits are considered weak by modern standards (NIST
SP 800-131A, OpenSSH defaults). The SshKey field currently accepts any well-formed RSA key regardless of
modulus length. Administrators who want to enforce a minimum bit length must add their own validation or
rely on the SSH server to reject weak keys downstream.

Proposed resolution

Add a per-field setting min_rsa_bits (default 2048) that the validator enforces when an
incoming key uses the ssh-rsa algorithm:

  1. Add the setting to SshKeyItem::defaultFieldSettings() and the field-settings form (a
    numeric input, visible when ssh-rsa is in the algorithm allowlist).
  2. Pass it through SshKeyItem::getConstraints() as a constraint option.
  3. Add a $minRsaBits property on SshKeyConstraint.
  4. In SshKeyConstraintValidator::validate(), when the parsed algorithm is
    ssh-rsa, read the modulus from the base64-decoded payload, compute its bit length, and emit a
    violation if it is below the threshold.
  5. Add a helper on Utils (e.g. getRsaModulusBitLength()) so the parsing logic
    stays out of the validator.
  6. Update the config schema and add unit tests covering accept/reject at the boundary.

Bit length is computable from the public key alone — RSA public-key payloads carry the modulus as an SSH
mpint after the algorithm string and public exponent. No new dependency required.

Comments

colan created an issue. See original summary.

  • colan committed 5def9e89 on 4.x
    Issue #3590025 by colan: Add minimum RSA key length enforcement to the...
colan’s picture

Status: Active » Fixed

Implemented on 4.x as commit 5def9e8.
SshKeyConstraintValidator now enforces a per-field min_rsa_bits setting (default 2048) whenever the incoming algorithm is ssh-rsa. The bit length is read via phpseclib3\Crypt\PublicKeyLoader::load(), which is already a hard dependency of this module — no new mpint-parsing code path and no additional Composer requirement.
SshKeyItem::getConstraints() falls back to defaultFieldSettings() when the saved setting is missing, so existing fields predating this change pick up the 2048 floor without an hook_update_N.

Unit tests cover the helper (Utils::getRsaModulusBitLength() for 2048-bit, 1024-bit, Ed25519, and garbage payloads) and the validator (acceptance at the threshold, rejection below it, and min_rsa_bits = 0 skipping the check).

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.