FIPS mode
SshClientOptions.FipsMode = true limits what a connection negotiates to FIPS-approved algorithms: NIST curves and Diffie-Hellman
groups, RSA and ECDSA host keys, AES, and HMAC-SHA2. Curve25519, Ed25519 and ChaCha20-Poly1305 are excluded.
When to use
- Policy requires FIPS 140-approved cryptography for SSH (government, regulated industries).
- You need to show which algorithms a connection may use.
Important
FIPS mode restricts what is negotiated. It does not make your process FIPS-validated: that depends on the platform's cryptographic module (Windows CNG, or OpenSSL in FIPS mode on Linux) and how it is configured.
Connect in FIPS mode
using var key = await SshPrivateKey.LoadAsync("id_ecdsa", cancellationToken: cancellationToken); // ECDSA or RSA: Ed25519 is not FIPS-approved
await using var client = await SshClient.ConnectAsync("example.com", 22, new SshClientOptions
{
UserName = "deploy",
PrivateKeys = [key],
HostKeyVerifier = KnownHostsVerifier.ForCurrentUser(StrictHostKeyChecking.Yes),
FipsMode = true,
}, cancellationToken);
// For an audit log: what was negotiated.
var a = client.Algorithms;
Console.WriteLine($"{a.KeyExchange}, {a.HostKeyAlgorithm}, {a.EncryptionClientToServer}, {a.MacClientToServer}");
What is allowed
| Kind | In FIPS mode |
|---|---|
| Key exchange | mlkem768nistp256-sha256 and mlkem1024nistp384-sha384 (post-quantum, .NET 10 with platform ML-KEM), ecdh-sha2-nistp256/384/521, diffie-hellman-group16-sha512, diffie-hellman-group14-sha256 |
| Host keys | ecdsa-sha2-nistp256/384/521, rsa-sha2-512, rsa-sha2-256 |
| Ciphers | aes256-gcm@openssh.com, aes128-gcm@openssh.com, aes256-ctr, aes192-ctr, aes128-ctr |
| MACs | hmac-sha2-512-etm@openssh.com, hmac-sha2-256-etm@openssh.com |
The NIST-curve ML-KEM hybrids keep a post-quantum key exchange in FIPS mode where both sides support it. See Algorithms for the full list and order.
Check a server before switching
// Which FIPS-approved host keys does a server have? (none means FipsMode cannot connect to it)
var keys = await SshClient.ScanHostKeysAsync("example.com", options: new SshHostKeyScanOptions { FipsMode = true },
cancellationToken: cancellationToken);
Notes and pitfalls
- User keys are yours to choose. FIPS mode governs the transport (key exchange, host keys, ciphers, MACs); it does not filter the keys you authenticate with. Ed25519 is not FIPS-approved, so use ECDSA or RSA keys.
- Connecting by alias.
FipsModeis anSshClientOptionssetting;SshConfigConnectOptionshas no equivalent. Withssh_config, restrictKexAlgorithms,HostKeyAlgorithms,CiphersandMACsto the lists above. - Servers with only Ed25519 host keys cannot be reached in FIPS mode: the connection fails with
KeyExchangeFailed. Add an ECDSA or RSA host key on the server. - Host key scans take
SshHostKeyScanOptions.FipsModetoo. - Strict key exchange (the Terrapin fix) is on in every mode.