$RodHat_
MOTD

OpenSSH 10.0 removes DSA entirely. NIST killed it three years ago.

Published by

OpenSSH 10.0 removes DSA entirely. NIST killed it three years ago.
Photo: AI-generated — no human photographer / RodHat AI Cover

DSA is gone from OpenSSH. Not “disabled by default unless you set a compile flag.” Not “present but generating a runtime warning.” Gone. OpenSSH 10.0 removed the code.

The deprecation notice has been in the release notes since 9.8, shipped in July 2024. OpenBSD gave the ecosystem two years and multiple major versions to find the DSA keys sitting in authorized_keys files and rotate them out. That is a more patient retirement window than the algorithm deserved.

NIST pulled the trigger first. FIPS 186-5, published February 3, 2023, removed DSA from the Digital Signature Standard outright. Not deprecated, removed. The document that defined DSA for thirty years no longer includes it. If you want to know why, the answer has been the same since 2010: DSA as specified in FIPS 186-2 and 186-4 is capped at 1024-bit keys. NIST declared 1024-bit security insufficient for new applications after 2010 and for existing ones after 2013. A 2048-bit DSA variant exists in the older spec, but implementation was sparse and deployment was essentially zero. In practice, DSA meant 1024 bits, and 1024 bits has been below the acceptable security margin for thirteen years.

Why the SSH use of DSA was especially bad

OpenSSH’s DSA implementation paired the algorithm with SHA-1, because that is what the original SSH protocol specified and what FIPS 186-2 required. SHA-1 has had known collision weaknesses since 2005. The SHAttered attack in 2017 produced a practical chosen-prefix SHA-1 collision. By 2020, chosen-prefix collisions were feasible for well-resourced attackers. For a signature scheme where forgery breaks the authentication model entirely, “well-resourced attacker can forge” is not an acceptable risk profile.

RFC 8332 gave SSH a path to RSA with SHA-256 and SHA-512 back in 2018. DSA never got an equivalent upgrade path. The algorithm does not support larger hashes in a straightforward way, the key size cannot be increased above 1024 bits without implementing a variant nobody supports, and the whole thing depends on a random nonce per signature where a weak RNG produces private key recovery in one shot. The DSA failure mode catalog is long and the fixes are architectural, not incremental. The OpenBSD developers knew this. NIST knew it. The IETF has known it for a decade.

What OpenSSH did and when

OpenSSH 9.8 (July 2024) disabled DSA host key generation by default and began warning on DSA user keys. OpenSSH 9.9 (October 2024) moved DSA key support behind a build-time option and stopped generating DSA host keys entirely unless the operator forced it. OpenSSH 10.0 removes that option. The build-time guard is gone. If you are running 10.0, DSA does not exist.

This is the right way to retire a broken primitive. Not “discouraged in documentation,” not “will be removed in a future release,” but an actual removal that forces the issue. The SSH ecosystem did not self-correct on DSA in the twelve years between NIST’s 2010 declaration and the 9.8 deprecation. Operators left old keys in place because old keys do not cause visible failures. Removal causes visible failures. Visible failures get fixed.

Auditing your authorized_keys files

If you are running OpenSSH 10.0 on any server, DSA public keys in authorized_keys will be silently rejected. The client gets a permission denied. The server log says nothing helpful. Audit before you upgrade.

# Find DSA keys in authorized_keys across all home directories
grep -r 'ssh-dss' /home/*/\.ssh/authorized_keys /root/.ssh/authorized_keys 2>/dev/null

# Find DSA private keys on a workstation
find ~/.ssh -name 'id_dsa' -o -name 'id_dsa*'

The replacement is Ed25519. It has been the correct default for a decade. If anyone on your team is still generating DSA keys, that is a process failure worth investigating.

ssh-keygen -t ed25519 -C "$(whoami)@$(hostname)-$(date +%Y-%m-%d)"

Rotate the old key out: add the new public key to authorized_keys on your servers, confirm login works, then remove the DSA entry. The whole operation takes five minutes per machine and the only reason it has taken until 2026 on most installations is that nobody was forced to do it sooner.

For host keys, ssh-keygen -A regenerates all missing host key types for the current OpenSSH version and skips DSA. If you are upgrading to 10.0, run it after the package update. The RSA and Ed25519 host keys will survive; only a DSA host key created by an older version would be missing, and you want it missing.

What stays

Everything else in OpenSSH 10.0 is either additive or unrelated to DSA. The mlkem768x25519-sha256 hybrid post-quantum KEX that became default in 9.9 is still default. Ed25519, ECDSA, and RSA-SHA256 keys all work. The removal is surgical.

OpenBSD did the work correctly here: years of deprecation warnings, a build flag in the penultimate version, and a clean removal in the next one. Compare this to the seventeen-year process for retiring the Secure Boot test keys that shipped in production hardware. Not every removal goes this cleanly. This one did.

The DSA keys in the authorized_keys files you have not audited are your problem now. The OpenSSH project has done its part.

Sources

  1. OpenSSH Release Notes (OpenBSD Project)
  2. FIPS 186-5: Digital Signature Standard (DSS) (National Institute of Standards and Technology)