FIPS-Compliant SSH RSA Keys (Air-Gapped)¶
Generate strong RSA SSH keys that meet FIPS requirements (NIST SP 800-131A: modulus ≥ 2048 bits) while remaining compatible with older non-FIPS / legacy systems.
All commands below run fully offline and are suitable for air-gapped environments.
Recommended Key Sizes¶
| Size | Security Strength | Recommendation |
|---|---|---|
| 2048 | ~112-bit | Minimum for FIPS. Best legacy compatibility. |
| 3072 | ~128-bit | Preferred balance of strength and broad support. |
| 4096 | higher | Strong, but slower; may be rejected by very old systems. |
Avoid keys smaller than 2048 bits — they are disallowed for signature generation under current FIPS guidance.
Generating Classic PEM (PKCS#1) Keys¶
Use ssh-keygen with -m PEM to produce the traditional format (-----BEGIN RSA PRIVATE KEY-----) that many older tools and systems expect.
2048-bit (maximum legacy compatibility)¶
3072-bit (stronger, still widely supported)¶
- Omit
-N ""(or supply a passphrase) if you want the private key encrypted. - The corresponding
.pubfile is created automatically and is in standard OpenSSH public-key format.
Generating PKCS#8 Keys¶
PKCS#8 uses the modern container format (-----BEGIN PRIVATE KEY----- or -----BEGIN ENCRYPTED PRIVATE KEY-----).
Unencrypted PKCS#8 (2048-bit)¶
Encrypted PKCS#8 (2048-bit)¶
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 \
-aes-256-cbc -out id_rsa_pkcs8_encrypted.pem
For a 3072-bit key, replace rsa_keygen_bits:2048 with rsa_keygen_bits:3072.
Extract the public key¶
# From unencrypted key
openssl rsa -in id_rsa_pkcs8.pem -pubout -out id_rsa_pkcs8.pub
# From encrypted key (will prompt for passphrase)
openssl rsa -in id_rsa_pkcs8_encrypted.pem -pubout -out id_rsa_pkcs8.pub
You can also convert an existing PEM key to PKCS#8:
openssl pkcs8 -topk8 -inform PEM -outform PEM \
-in id_rsa_fips_legacy -out id_rsa_pkcs8.pem -nocrypt
Printing Key Fingerprints¶
# SHA256 fingerprint (recommended)
ssh-keygen -l -f id_rsa_fips_legacy.pub
# With randomart
ssh-keygen -l -v -f id_rsa_fips_legacy.pub
# MD5 fingerprint (legacy style)
ssh-keygen -l -E md5 -f id_rsa_fips_legacy.pub
# Works on private keys as well
ssh-keygen -l -f id_rsa_pkcs8.pem
The fingerprint is always derived from the public key material, so private and public files for the same key produce identical results.
Quick Verification (Air-Gapped)¶
# Integrity check
openssl rsa -in id_rsa_pkcs8.pem -check -noout
# Expected: RSA key ok
# Confirm modulus size and structure
openssl rsa -in id_rsa_pkcs8.pem -text -noout | head -5
# Confirm format
head -1 id_rsa_pkcs8.pem
# Expected: -----BEGIN PRIVATE KEY----- (or ENCRYPTED PRIVATE KEY)
For classic PEM keys generated by ssh-keygen -m PEM:
File Permissions¶
Compatibility Notes¶
- FIPS systems: Prefer
rsa-sha2-256andrsa-sha2-512signature algorithms. 2048-bit and larger RSA keys are acceptable. - Legacy systems: Many older implementations only understand the traditional
ssh-rsa(SHA-1) signature and the PKCS#1 private-key format. Keep a-m PEMcopy if you must interoperate with them. You may need to explicitly enablessh-rsainPubkeyAcceptedAlgorithms/HostKeyAlgorithmson the FIPS side (note that this can affect FIPS mode status on some platforms). - Private-key formats:
- PKCS#1 (
BEGIN RSA PRIVATE KEY) — best for very old tools. - PKCS#8 (
BEGIN PRIVATE KEY) — preferred by modern OpenSSL, Java, and most contemporary software. - OpenSSH native format (
BEGIN OPENSSH PRIVATE KEY) — requires OpenSSH ≥ 7.8.
Air-Gapped Best Practices¶
- Generate keys on the air-gapped system itself whenever possible (especially if it is running in FIPS mode so the validated RNG is used).
- Transfer public keys and, when necessary, private keys only via secure physical media.
- Never expose private keys over a network.
- Document the fingerprint of every deployed key for verification.
- Prefer 3072-bit keys unless you have a concrete legacy-system constraint that requires 2048-bit.
Summary of Common Commands¶
| Goal | Command |
|---|---|
| 2048-bit PEM key | ssh-keygen -t rsa -b 2048 -m PEM -f keyname |
| 3072-bit PEM key | ssh-keygen -t rsa -b 3072 -m PEM -f keyname |
| Unencrypted PKCS#8 | openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out key.pem |
| Encrypted PKCS#8 | openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -aes-256-cbc -out key.pem |
| Extract public key | openssl rsa -in private.pem -pubout -out public.pub |
| Show fingerprint | ssh-keygen -l -f key.pub |
| Verify key | openssl rsa -in private.pem -check -noout |
All key material should be treated as sensitive. Regenerate keys on your own systems for production use.