CWE-326: Inadequate Encryption Strength
Overview
Inadequate Encryption Strength occurs when cryptography that is otherwise theoretically sound does not provide sufficient security strength for the data it protects - an RSA key that is too short, a key size or work factor below the level the data requires, or parameters that leave too little resistance to attack. Algorithms that are themselves broken or deprecated are closely related but belong to CWE-327 (Use of a Broken or Risky Cryptographic Algorithm); they appear below as remediation context rather than as canonical examples of this weakness.
Relationship to Other CWEs
- CWE-326 (this page) - cryptography that is theoretically sound but not strong enough for what it protects: a key short enough to search, or a work factor low enough to guess against at scale
- CWE-327 (Use of a Broken or Risky Cryptographic Algorithm) - the neighbouring Class, for an algorithm or mode that is broken or deprecated rather than merely under-sized. MITRE records no relationship between the two; both are Class children of CWE-693, and they overlap enough that the same finding is often reported as either
- CWE-328 (Use of Weak Hash) - a Base child of this page and of CWE-327; use it once the finding is known to be a hash
- CWE-916 (Use of Password Hash With Insufficient Computational Effort) - under CWE-328, for password storage, where the problem is that the hash is fast rather than that the key is short
- CWE-693 (Protection Mechanism Failure) - the Pillar this page sits under
OWASP Classification
A04:2025 - Cryptographic Failures
Risk
High: An attacker who obtains ciphertext or stored password hashes can break them offline, recovering the plaintext without needing further access to the application. Unauthenticated modes additionally let ciphertext be altered without detection.
Remediation Steps
Core Principle: Never allow cryptographic strength to be determined by legacy compatibility or client input; cryptographic algorithms, protocols, and key sizes must be centrally defined, server-controlled, and constrained to secure minimums.
Locate the inadequate encryption strength
- Find where the code selects cryptographic algorithms and key sizes
- Identify under-strength parameters: short keys, low work factors, and small curves. DES, 3DES/TDEA, RC4, MD5, SHA-1 and AES-ECB are worth finding in the same sweep, but they are broken or deprecated rather than under-sized, so file those under CWE-327. An unauthenticated mode is a third case and not categorically a finding: CBC and CTR are sound inside a complete construction that authenticates separately, such as encrypt-then-MAC, so judge the construction rather than the mode name
- Check key sizes: RSA below 2048 bits is clearly weak and RSA-2048 is accepted by NIST only through 2030, so treat anything below 3072 as needing a plan; also check AES keys and ECC curves below the required security level
- Determine usage: encryption, hashing, key derivation, password storage, digital signatures
Use strong, industry-standard algorithms (Primary Defense)
- Encryption: Use authenticated encryption such as AES-GCM or ChaCha20-Poly1305 with keys sized for the data lifetime and compliance requirements
- Hashing: Use SHA-256, SHA-384, SHA-512 (not MD5, SHA-1)
- Password hashing: Use Argon2id first, then scrypt. Where FIPS-140 requirements apply, use PBKDF2-HMAC-SHA256 with 600,000 or more iterations. bcrypt should normally be retained only for legacy systems where Argon2id and scrypt are unavailable. For existing bcrypt deployments, use a work factor of at least 10 and tune it as high as authentication performance permits. Be aware that most bcrypt implementations have a 72-byte password input limit. Stored hashes are normally upgraded on the user's next successful authentication, though a forced reset or password expiry is the other way to complete a migration
- Public key: Use RSA-3072 for new keys, or ECC P-256/X25519 or stronger. RSA-2048 is rated at 112-bit strength; NIST SP 800-57 Part 1 Table 4 marks that strength Acceptable for applying protection through 2030 and Disallowed from 2031. The restriction is on the operation, not on when the key was generated: from 2031 an RSA-2048 key may not be used to encrypt, sign or wrap, including a key you generate today. Processing what is already protected - verifying an old signature, decrypting old ciphertext - stays permitted as legacy use. Permission to decrypt is not the same as the data still being adequately protected: SP 800-57 Section 5.6.4 asks how long the data itself has to stay secure, so anything that must remain confidential past 2030 needs a stronger scheme now rather than a legacy-use permit later. RSA-2048 is not broken today, but it matters most for long-lived signing keys and archived ciphertext
- Key derivation: Use Argon2 or scrypt, or PBKDF2-HMAC-SHA256 with 600,000 or more iterations where PBKDF2 is required
Enforce adequate key lengths
- Symmetric encryption: AES-128 or larger. AES-128 carries 128-bit security strength in NIST's comparable-strength tables and is not a CWE-326 finding on its own; AES-256 is the sensible default for new work and for anything with a long retention period, and is worth mandating as policy - but treat an existing AES-128 deployment as a margin decision, not a defect to be remediated
- Asymmetric encryption: 3072 bits for new RSA keys, which is the 128-bit strength level; go to 4096 only where a policy or a very long retention period asks for it, since it buys about 150-bit strength rather than the doubling the number suggests. For ECC a 256-bit curve (P-256, X25519) is the same 128-bit strength level as RSA-3072 - an elliptic-curve key is roughly twice the length of the strength it delivers, so 256 bits here and 256 bits of AES are not the same amount of security
- HMAC keys: Use 256-bit random keys by default. NIST ties the requirement to key entropy and the target security strength rather than setting one universal floor
- Password hashing: Proper work factors tuned on production-class hardware, starting from current OWASP minimums
- Rotate keys: Set a cryptoperiod per key type, usage, data volume and environment rather than assuming a year - NIST's ranges for symmetric data-encryption keys run from days at very high volumes to about two years at low ones - and replace a compromised key immediately
Use secure cryptographic libraries
- Use established libraries: OpenSSL, Bouncy Castle, Java JCA, .NET System.Security.Cryptography, Python cryptography
- Do not implement your own algorithms or modes
- Prefer a library's high-level safe APIs, and constrain the permitted algorithms and modes explicitly: established libraries still expose low-level and legacy primitives
- Apply security patches for cryptographic libraries promptly
Monitor and audit cryptographic usage
- Review algorithm choices, key sizes, and work factors on a schedule
- Grep the codebase for "DES", "RC4", "MD5" and "SHA1", or let static analysis find them; AES-128 is worth locating if policy mandates AES-256, but it is a policy hit rather than a weak algorithm
- Log cryptographic failures such as decryption errors and invalid signatures
- Track the key rotation schedule and alert on overdue rotations
Test the encryption strength fix
- Confirm weak algorithms are gone from code, configuration, and stored data
- Round-trip encryption and decryption with the new algorithm and key size
- Check performance; AES-256 costs little over AES-128
- Test the migration from weak to strong encryption, following the migration guidance below
- Confirm keys are stored securely and rotated on schedule
- Re-scan to confirm the finding is resolved
Common Vulnerable Patterns
- Using outdated or weak algorithms (e.g., DES, RC4, MD5)
- Using short or default keys
- Implementing custom cryptographic solutions
Generic Pattern: Vulnerable
Weak Encryption
// VULNERABLE - pseudo-code
algorithm = "DES" or "RC4" or "MD5"
key_size = 56 bits (DES) or RSA-1024 // Too small for their own algorithm types
cipher_mode = ECB // Reveals patterns
iterations = 1000 // Too few for key derivation
Why this is vulnerable: DES uses a 56-bit key that can be brute-forced in hours with modern hardware, while RC4 has known biases in its keystream that leak plaintext. RSA-1024 is rated at roughly 80-bit strength; NIST deprecated it through 2013 and disallowed it for applying protection from 1 January 2014. A key length only means something against its own algorithm type, and the numbers are not comparable across types: 1024 bits is far too short for RSA, while 128 bits is a full 128-bit security strength for AES and not a finding on its own - an RSA key has to be an order of magnitude longer than a symmetric one to deliver the same strength, because factoring beats it long before key search does. MD5 is cryptographically broken with practical collision attacks, which is what rules it out for digital signatures; it is unsuitable for password hashing for a separate reason, that it is fast enough to guess against at billions of attempts per second. ECB mode encrypts identical plaintext blocks to identical ciphertext, revealing data patterns - the "ECB penguin" image is the well-known demonstration. With only 1000 PBKDF2 iterations the work factor is far too low: a single high-end GPU tests on the order of millions of PBKDF2-HMAC-SHA256 guesses per second at that setting, against the 600,000 or more iterations current guidance requires. Billions per second is the rate for a raw fast hash such as MD5 or SHA-1, not for PBKDF2 at any sane iteration count.
Secure Patterns
Generic Pattern: Strong Encryption
// SECURE - pseudo-code
// Symmetric: the mode belongs here, and it authenticates as well as encrypts
algorithm = "AES-256-GCM"
key_size = 256 bits
cipher_mode = GCM
// Asymmetric: no cipher mode applies - the padding scheme is the choice (RFC 8017)
rsa_encrypt = "RSA-3072 with OAEP"
rsa_sign = "RSA-3072 with PSS"
// or an elliptic-curve equivalent at the same 128-bit strength: X25519, P-256
password_hashing = "argon2id"
// scrypt if Argon2id is unavailable
// PBKDF2-HMAC-SHA256 where FIPS requirements apply
// bcrypt only for an existing legacy deployment
iterations = 600000+ // OWASP minimum for PBKDF2-HMAC-SHA256
Why this works: AES-GCM provides authenticated encryption, detecting tampering and preventing many chosen-ciphertext attacks that affect unauthenticated encryption. RSA-3072 provides a stronger long-term margin than RSA-2048, while modern ECC options can provide comparable security with smaller keys. RSA takes no cipher mode - GCM and its relatives are symmetric-only - so what it needs chosen is the padding scheme: OAEP for encryption and PSS for signatures. Leaving RSA encryption on PKCS#1 v1.5 padding is CWE-780 (Use of RSA Algorithm without OAEP). Argon2id and scrypt are preferred for new work and incorporate unique salts and tunable work factors; properly configured bcrypt remains suitable for legacy deployments, and PBKDF2-HMAC-SHA256 with 600,000 or more iterations is appropriate where PBKDF2 is required. Tune parameters on production-class hardware rather than treating any single number as permanently sufficient.
Migration Considerations
Changing the key size or algorithm used for new encryption does not affect existing ciphertext: it stays decryptable under the key and algorithm that produced it. What migration costs is carrying both schemes until the old one is retired.
What Breaks
- Two schemes in flight: Until every record is migrated, the read path has to select the key and algorithm each record was written under, which is what the dual-read step below is for
- Old key custody: Retain controlled access to the old key for as long as any record still depends on it, then retire it deliberately - dropping it early is what actually makes data unreadable
- Re-encryption is a choice of timing, not a prerequisite: Re-encrypt under the new scheme either eagerly in batches or lazily as records are read, depending on volume and how soon the old key must go
- Performance: AES-256 costs slightly more than AES-128
Migration Approach
The approach is the same as for CWE-327, which has the detailed steps:
- Implement dual-read supporting both key sizes
- Decrypt with old key, re-encrypt with new key size
- Batch migrate stored encrypted data
- Monitor migration progress
- Remove old key support once every record is migrated
Testing Recommendations
- Test encryption/decryption with new key size
- Verify dual-read handles both old and new keys
- Load test: measure performance impact of larger keys
- Test migration script on sample dataset
Language-Specific Guidance
- C# - AesGcm, RSA, BCrypt
- Go - crypto/aes with GCM, ChaCha20-Poly1305, Argon2
- Java - AES-256, KeyGenerator, Cipher configuration
- JavaScript/Node.js - crypto.createCipheriv with AES-256-GCM
- Python - cryptography library, Fernet, AES-256-GCM
Additional Resources
- CWE-326: Inadequate Encryption Strength
- NIST SP 800-131A Rev 2: Transitioning the Use of Cryptographic Algorithms and Key Lengths - RSA-2048 provides 112-bit security strength, which is currently acceptable for applying protection
- NIST SP 800-57 Part 1 Rev 5: Recommendation for Key Management - Table 4 is the source for the 2030 date: 112-bit strength is Acceptable for applying protection (generating keys, encrypting, signing) through 2030 and Disallowed from 2031, while processing already-protected data stays permitted as legacy use
- OWASP Cryptographic Storage Cheat Sheet
- OWASP Password Storage Cheat Sheet - the source for the PBKDF2 iteration count, bcrypt work factor, and Argon2 parameters used here
- OWASP Top 10 2025 A04: Cryptographic Failures