Skip to content

Commit a0f88ba

Browse files
committed
security(keygen): use OsRng instead of thread_rng for cryptographic key generation
Replace thread_rng() with OsRng for SSH key generation, which provides stronger security guarantees: **Why OsRng is better:** - Direct access to OS CSPRNG (not cached) - Stateless (no internal state to leak) - No fork-safety concerns - Explicitly designed for cryptographic operations **Why this change:** - thread_rng() prioritizes performance over crypto guarantees - rand 0.8 didn't clearly document crypto status of ThreadRng - OsRng is the recommended RNG for SSH key generation **Compatibility note:** Cannot upgrade to rand 0.9 yet because ssh-key 0.6 requires rand_core 0.6. The RustCrypto ecosystem is still migrating to rand_core 0.9. When ssh-key releases a version compatible with rand_core 0.9, we can upgrade. Changes: - tools/ssh_keygen/src/main.rs: Use rand::rngs::OsRng (3 locations) - tools/ssh_keygen/Cargo.toml: Add comment about rand 0.9 compatibility Tests: All tests pass (3/3) with OsRng
1 parent 4cb46e7 commit a0f88ba

File tree

2 files changed

+7
-5
lines changed

2 files changed

+7
-5
lines changed

tools/ssh_keygen/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ anyhow = "1.0"
1010
clap = { version = "4.5", features = ["derive"] }
1111
ssh-key = { version = "0.6", features = ["ed25519", "rsa", "ecdsa", "rand_core"] }
1212
rand = "0.8"
13-
# rand_core will be resolved transitively to 0.6 (compatible with ssh-key)
13+
# Uses OsRng for cryptographic key generation (OS-backed CSPRNG)
14+
# Note: Cannot upgrade to rand 0.9 until ssh-key supports rand_core 0.9
1415

1516
[dev-dependencies]
1617
tempfile = "3.23"

tools/ssh_keygen/src/main.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,9 @@ fn main() -> Result<()> {
111111
.to_algorithm(cli.bits)
112112
.context("Failed to determine key algorithm")?;
113113

114-
// Generate the private key
115-
let mut private_key = PrivateKey::random(&mut rand::thread_rng(), algorithm)
114+
// Generate the private key using OS CSPRNG
115+
// OsRng is the recommended cryptographic RNG for key generation
116+
let mut private_key = PrivateKey::random(&mut rand::rngs::OsRng, algorithm)
116117
.context("Failed to generate private key")?;
117118

118119
// Set comment if provided
@@ -212,7 +213,7 @@ mod tests {
212213

213214
// Generate key using our algorithm
214215
let algorithm = cli.key_type.to_algorithm(cli.bits)?;
215-
let private_key = PrivateKey::random(&mut rand::thread_rng(), algorithm)?;
216+
let private_key = PrivateKey::random(&mut rand::rngs::OsRng, algorithm)?;
216217

217218
// Verify we can encode both private and public keys
218219
let _private_data = private_key.to_openssh(LineEnding::LF)?;
@@ -224,7 +225,7 @@ mod tests {
224225
#[test]
225226
fn test_rsa_key_generation() -> Result<()> {
226227
let algorithm = KeyType::Rsa.to_algorithm(Some(2048))?;
227-
let private_key = PrivateKey::random(&mut rand::thread_rng(), algorithm)?;
228+
let private_key = PrivateKey::random(&mut rand::rngs::OsRng, algorithm)?;
228229

229230
// Verify we can encode both keys
230231
let _private_data = private_key.to_openssh(LineEnding::LF)?;

0 commit comments

Comments
 (0)