Insecure encryption algorithm - DSA
Need
Replacement of DSA with a modern digital signature algorithm
Context
• Usage of Rust 1.75+ for building application services
• Usage of the dsa crate for digital signatures
• Usage of the ed25519-dalek crate for digital signatures
Description
1. Non compliant code
use dsa::{Components, KeySize, SigningKey};
use rand::rngs::OsRng;
fn generate_signing_key() -> SigningKey {
// DSA is no longer approved for creating new signatures
let components = Components::generate(&mut OsRng, KeySize::DSA_2048_256);
SigningKey::generate(&mut OsRng, components)
}The `generate_signing_key` function below creates a key pair with the Digital Signature Algorithm from the `dsa` crate. NIST removed DSA from the approved signature algorithms in FIPS 186-5, and it may only be used to verify signatures created before that change. DSA is also fragile: every signature needs a fresh secret nonce, and a nonce that is reused or slightly biased, for example because of a weak random number generator, lets an attacker compute the private key from two signatures. This is how the private keys of real systems have been recovered. With the private key, an attacker can sign software updates, tokens or documents that every verifier accepts as genuine.
2. Steps
• Stop generating DSA keys and signatures with the `dsa` crate or with `openssl::dsa`.
• Use Ed25519 (`ed25519-dalek`) for new signatures, or ECDSA over P-256 (`p256`) when NIST curves are required.
• Generate signing keys from `OsRng` and store them in a key management service or a hardware security module.
• Keep DSA verification only for signatures created before the migration, and plan their reissue.
• Rotate the key pairs and update the public keys distributed to every verifier.
3. Secure code example
use ed25519_dalek::{Signature, Signer, SigningKey};
use rand::rngs::OsRng;
fn generate_signing_key() -> SigningKey {
// Ed25519 is approved in FIPS 186-5 and signs deterministically
SigningKey::generate(&mut OsRng)
}
...The corrected code generates an Ed25519 key with the `ed25519-dalek` crate, using `OsRng` from the operating system. Ed25519, approved in FIPS 186-5, is deterministic: the per-signature nonce is derived from the private key and the message, so signing does not depend on the quality of a random number generator at that moment and a nonce can never be reused by accident. Its keys are 32 bytes, signing and verification are fast, and the implementation runs in constant time. When a standard requires NIST curves, ECDSA over P-256 from the `p256` crate is the alternative. In both cases, existing DSA keys should be retired and the signatures that verifiers trust should be reissued with the new key.
References
• 261. Insecure encryption algorithm - DSA