Use of a Broken or Risky Cryptographic Algorithm

Description

Use of a Broken or Risky Cryptographic Algorithm occurs when software uses cryptographic algorithms or protocols that have known weaknesses, are outdated, or are inappropriate for the security context. This includes using deprecated hash functions (MD5, SHA-1), weak encryption algorithms (DES, RC4), broken protocols (SSLv2, SSLv3), insufficient key lengths, weak random number generators, or homegrown cryptography. When cryptographic protection fails, data confidentiality, integrity, and authentication are compromised, potentially exposing sensitive information to attackers.

Risk

Weak cryptography provides false security—systems appear protected but can be broken. MD5 and SHA-1 collisions have been practically demonstrated, enabling forged certificates and document tampering. DES can be brute-forced in hours. RC4 has statistical biases enabling plaintext recovery. A5/1/A5/2 cellular encryption has been broken, allowing real-time mobile call interception with commercial tools. Historical breaches have resulted from relying on deprecated algorithms that were "good enough" at deployment but later became vulnerable. OWASP ranks Cryptographic Failures as #2 in their Top 10.

Solution

Use only current, well-vetted cryptographic algorithms. For encryption: AES-256-GCM or ChaCha20-Poly1305. For hashing: SHA-256, SHA-3, or BLAKE2. For password hashing: Argon2, bcrypt, or scrypt. For key exchange: ECDH with P-256 or X25519. Use TLS 1.2+ with strong cipher suites. Never implement custom cryptography. Use established libraries (OpenSSL, libsodium, BoringSSL). Follow NIST guidelines and industry standards. Implement cryptographic agility to allow algorithm updates. Regularly audit cryptographic implementations.

Common Consequences

ImpactDetails
ConfidentialityScope: Data Exposure

Weak encryption can be broken, exposing all protected data to attackers.
IntegrityScope: Forgery

Broken hash algorithms enable collision attacks, allowing forged documents, certificates, and signatures.
AuthenticationScope: Credential Theft

Weak password hashing or authentication protocols expose user credentials.

Example Code + Solution Code

Vulnerable Code

// VULNERABLE: MD5 for password hashing
import java.security.MessageDigest;

public String hashPassword(String password) {
    MessageDigest md = MessageDigest.getInstance("MD5");  // Broken!
    byte[] hash = md.digest(password.getBytes());
    return Base64.getEncoder().encodeToString(hash);
}

// VULNERABLE: DES encryption
import javax.crypto.Cipher;

public byte[] encrypt(byte[] data, Key key) {
    Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");  // Weak!
    cipher.init(Cipher.ENCRYPT_MODE, key);
    return cipher.doFinal(data);
}

// VULNERABLE: SHA-1 for signatures
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");  // Collision attacks!
# VULNERABLE: MD5 for integrity checking
import hashlib

def verify_file(filepath, expected_hash):
    md5 = hashlib.md5()  # Broken - collisions possible!
    with open(filepath, 'rb') as f:
        md5.update(f.read())
    return md5.hexdigest() == expected_hash

# VULNERABLE: Weak random for tokens
import random
def generate_token():
    return str(random.randint(0, 999999))  # Predictable!
// VULNERABLE: Weak crypto in Node.js
const crypto = require('crypto');

// RC4 is broken
const cipher = crypto.createCipheriv('rc4', key, '');

// DES is weak
const desCipher = crypto.createCipheriv('des', key, iv);

// MD5 for verification
const hash = crypto.createHash('md5').update(data).digest('hex');

Fixed Code

// SAFE: Modern password hashing with Argon2
import org.bouncycastle.crypto.generators.Argon2BytesGenerator;
import org.bouncycastle.crypto.params.Argon2Parameters;

public String hashPasswordSafe(String password) {
    Argon2Parameters params = new Argon2Parameters.Builder(Argon2Parameters.ARGON2_id)
        .withMemoryAsKB(65536)
        .withIterations(3)
        .withParallelism(4)
        .withSalt(generateSecureSalt())
        .build();

    Argon2BytesGenerator generator = new Argon2BytesGenerator();
    generator.init(params);
    byte[] hash = new byte[32];
    generator.generateBytes(password.toCharArray(), hash);
    return Base64.getEncoder().encodeToString(hash);
}

// SAFE: AES-256-GCM encryption
public byte[] encryptSafe(byte[] data, SecretKey key) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
    byte[] iv = new byte[12];  // 96-bit IV for GCM
    SecureRandom.getInstanceStrong().nextBytes(iv);

    cipher.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(128, iv));
    byte[] ciphertext = cipher.doFinal(data);

    // Prepend IV to ciphertext
    byte[] result = new byte[iv.length + ciphertext.length];
    System.arraycopy(iv, 0, result, 0, iv.length);
    System.arraycopy(ciphertext, 0, result, iv.length, ciphertext.length);
    return result;
}

// SAFE: SHA-256 for integrity
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
# SAFE: Modern password hashing
from argon2 import PasswordHasher

ph = PasswordHasher()

def hash_password_safe(password):
    return ph.hash(password)

def verify_password_safe(hash, password):
    try:
        return ph.verify(hash, password)
    except:
        return False

# SAFE: SHA-256 for integrity
import hashlib

def verify_file_safe(filepath, expected_hash):
    sha256 = hashlib.sha256()
    with open(filepath, 'rb') as f:
        for chunk in iter(lambda: f.read(8192), b''):
            sha256.update(chunk)
    return sha256.hexdigest() == expected_hash

# SAFE: Cryptographically secure random
import secrets

def generate_token_safe():
    return secrets.token_urlsafe(32)  # 256 bits of entropy
// SAFE: Modern crypto in Node.js
const crypto = require('crypto');

// AES-256-GCM
function encrypt(plaintext, key) {
    const iv = crypto.randomBytes(12);
    const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);

    let encrypted = cipher.update(plaintext, 'utf8', 'hex');
    encrypted += cipher.final('hex');
    const authTag = cipher.getAuthTag();

    return { iv: iv.toString('hex'), encrypted, authTag: authTag.toString('hex') };
}

// SHA-256 for hashing
const hash = crypto.createHash('sha256').update(data).digest('hex');

// Secure random tokens
const token = crypto.randomBytes(32).toString('hex');

Exploited in the Wild

A5/1 GSM Encryption (Cellular, Ongoing)

A5/1 and A5/2 cellular encryption algorithms are cryptanalytically broken. Commercial tools exist to intercept and decrypt mobile phone conversations in real-time using rogue base stations.

SHA-1 Collision (SHAttered, 2017)

Google and CWI Amsterdam demonstrated practical SHA-1 collisions, creating two different PDF files with the same SHA-1 hash. This enables certificate forgery and document tampering.

MD5 Certificate Forgery (Flame Malware, 2012)

The Flame malware used MD5 collision attacks to forge Microsoft certificates, enabling code signing with apparently legitimate Microsoft signatures.


Tools to test/exploit

  • HashClash — MD5 and SHA-1 collision generator.

  • SSLyze — identify weak TLS configurations.

  • CryptoLyzer — cryptographic protocol analyzer.


CVE Examples


References

  1. MITRE. "CWE-327: Use of a Broken or Risky Cryptographic Algorithm." https://cwe.mitre.org/data/definitions/327.html

  2. OWASP. "A02:2021 – Cryptographic Failures." https://owasp.org/Top10/A02_2021-Cryptographic_Failures/

  3. NIST. "Cryptographic Standards and Guidelines." https://csrc.nist.gov/Projects/Cryptographic-Standards-and-Guidelines