Description
Weak cryptographic algorithm usage (CWE-327 — Use of a Broken or Risky Cryptographic Algorithm) describes situations where an application employs cryptographic primitives that have been demonstrated to be insecure through academic research, practical attacks, or computational advances. This includes hash functions (MD5, SHA-1), symmetric ciphers (DES, 3DES, RC4), and asymmetric key algorithms with insufficient key lengths (RSA-512, RSA-1024). When these algorithms protect sensitive data, the protection they provide is materially weaker than assumed — and in many cases, can be entirely defeated by a motivated attacker.
The OWASP Top 10 A02:2021 — Cryptographic Failures covers all failures related to cryptography, including both the wrong algorithm choice and the absence of cryptography entirely. CWE-327 is specifically about the algorithm selection. The risk is not always theoretical: MD5 collision attacks are computationally trivial with modern hardware, SHA-1 certificate collisions were practically demonstrated by the SHAttered attack in 2017, and RC4 biases allow session decryption in WPA and TLS configurations.
Weak cryptography is common because: legacy codebases written when these algorithms were acceptable have not been updated; developers copy-paste code without understanding the security context; and some frameworks default to weak algorithms for compatibility. The vulnerability surfaces in password hashing, data encryption, digital signatures, TLS configuration, and integrity verification.
How It Works
MD5 for password hashing is one of the most dangerous manifestations. MD5 is a fast hash function — an attacker with a modern GPU can compute billions of MD5 hashes per second using tools like Hashcat:
# Cracking MD5 hashes from a database dump
hashcat -m 0 -a 0 hashes.txt /usr/share/wordlists/rockyou.txt --rules-file best64.rule
# Speed on a modern GPU: ~10 billion MD5/s
# Time to crack "password123" MD5: milliseconds
MD5 is unsalted in many implementations, making rainbow table attacks trivially effective. A 32-character MD5 hash like 5f4dcc3b5aa765d61d8327deb882cf99 is instantly recognizable and reversible for common passwords via CrackStation or similar online lookup tables.
DES and 3DES have effective key sizes of 56 bits and approximately 112 bits respectively. DES can be brute-forced in under 24 hours with dedicated hardware. 3DES is deprecated by NIST (effective 2024) due to the Sweet32 birthday attack, which allows plaintext recovery after approximately 785 GB of ciphertext encrypted under the same key.
RC4 stream cipher has known statistical biases: the first bytes of the keystream are non-random, and long-term key reuse allows decryption. In WPA/TKIP and older TLS configurations, RC4 biases can be exploited by tools like BEAST and RC4NOMORE.
SHA-1 for digital signatures allows collision attacks. The SHAttered attack (2017) produced two different PDF files with identical SHA-1 hashes for approximately $75,000 in cloud computing time — now replicable for much less. SHA-1 is no longer trusted by major browsers for TLS certificates.
# Vulnerable: MD5 password hashing
import hashlib
hashed = hashlib.md5(password.encode()).hexdigest() # NEVER do this
# Vulnerable: DES encryption
from Crypto.Cipher import DES
cipher = DES.new(key, DES.MODE_ECB) # DES is broken
Impact
- Password database compromise — weak password hashes (MD5, SHA-1, unsalted SHA-256) are cracked in minutes to hours using GPU-accelerated tools like Hashcat.
- Data decryption — data encrypted with DES, 3DES, or RC4 can be decrypted with sufficient resources or through known attacks.
- Signature forgery — SHA-1 collision attacks allow creating malicious documents with valid signatures.
- Session hijacking — RC4 biases in TLS or WPA allow decryption of session tokens.
- Compliance failure — PCI-DSS, FIPS 140-2, and NIST guidelines explicitly prohibit these algorithms; using them triggers audit failures and regulatory penalties.
- TLS downgrade — presence of weak cipher suites in TLS negotiation enables protocol downgrade attacks.
Detection
- Audit password hashing — search the codebase for calls to
md5,sha1,sha256used for password storage. Confirm whether bcrypt, scrypt, or Argon2 is used instead. - Scan TLS configuration with testssl.sh or sslyze — identify supported cipher suites and flag RC4, DES, 3DES, NULL, EXPORT, and ANON suites.
- Check code for weak cipher imports — search for
DES,RC4,MD5,SHA1in cryptographic contexts (not in non-security contexts like checksums). Use Semgrep rules for cryptographic weaknesses. - Inspect token signing algorithms — decode JWTs and verify the
algheader isRS256orES256, notHS256with a weak secret, and nevernone. - Review certificate and key sizes — check TLS certificates and SSH host keys for RSA keys below 2048 bits and DSA keys (deprecated entirely).
- Check mobile app binary for calls to deprecated cryptographic APIs: iOS
CCAlgorithmDES, Androidjavax.crypto.Cipher.getInstance("DES/ECB/NoPadding").
Remediation
Replace MD5 and SHA-1 for password hashing with Argon2id (preferred), bcrypt (work factor ≥ 12), or scrypt:
# Python — use passlib or argon2-cffi
from argon2 import PasswordHasher
ph = PasswordHasher()
hash = ph.hash(password) # Store this
ph.verify(hash, password) # Verify
Replace DES/3DES/RC4 with AES-256-GCM (authenticated encryption) or ChaCha20-Poly1305. Both provide confidentiality and integrity.
Replace SHA-1 for integrity and signature contexts with SHA-256 or SHA-3.
Update TLS configuration to TLS 1.2+ with only strong cipher suites. Disable TLS 1.0, TLS 1.1, SSLv3, and all RC4, DES, 3DES, EXPORT, and NULL cipher suites. Use Mozilla SSL Configuration Generator for server-specific configurations.
Upgrade RSA key sizes to a minimum of 2048 bits (3072 or 4096 preferred for new keys). Consider migrating to elliptic curve cryptography (ECDSA P-256, Ed25519) for better performance at equivalent security levels.
