Description
PBKDF1 is a legacy KDF based only on MD5 or SHA-1 and must not be used for new password storage, regardless of its iteration count. For PBKDF2, fewer than 600,000 iterations with HMAC-SHA256 or 220,000 with HMAC-SHA512 makes offline guessing against leaked hashes easier. If existing compatibility requires HMAC-SHA1, use at least 1,400,000 iterations, but do not choose it for a new system.
Potential impact
- Lower cost of password cracking.
- Greater likelihood of recovering passwords from leaked hashes.
- Increased risk of attacks that reuse compromised credentials.
Remediation
- Use PBKDF1 only for legacy compatibility and migrate existing password hashes to a safer KDF when users log in.
- Configure PBKDF2-HMAC-SHA256 with at least the OWASP recommendation of 600,000 iterations and review the policy regularly.
- For PBKDF2-HMAC-SHA512, use at least 220,000 iterations.
- For legacy PBKDF2-HMAC-SHA1, use at least 1,400,000 iterations and migrate to a more modern KDF at login.
- Prefer a dedicated password hashing algorithm such as Argon2id, bcrypt, or scrypt where possible.
- Specify the iteration count explicitly instead of relying on CryptoSwift's low default.
- Manage the iteration count through configuration and validate that it cannot fall below a safe minimum.
Examples
Before
swift
import CryptoSwift
func deriveWithTooFewIterations(
password: [UInt8], salt: [UInt8]
) throws -> [UInt8] {
return try PKCS5.PBKDF2(
password: password,
salt: salt,
iterations: 90000,
keyLength: 32,
variant: .sha2(.sha256)
).calculate()
}
func deriveWithObsoletePBKDF1(password: [UInt8]) throws -> [UInt8] {
let salt = (0..<8).map { _ in UInt8.random(in: 0...UInt8.max) }
return try PKCS5.PBKDF1(
password: password,
salt: salt,
iterations: 1000,
keyLength: 16
).calculate()
}
After
swift
import CryptoSwift
func derivePasswordKey(password: [UInt8], salt: [UInt8]) throws -> [UInt8] {
return try PKCS5.PBKDF2(
password: password,
salt: salt,
iterations: 600000,
keyLength: 32,
variant: .sha2(.sha256)
).calculate()
}
Explanation:
- Before: A low iteration count for PBKDF2-HMAC-SHA256 speeds up an attacker's offline guesses. Even with a random salt, PBKDF1 remains a legacy MD5/SHA-1-based KDF and is unsuitable for new password hashes.
- After: PBKDF2-HMAC-SHA256 uses the currently recommended minimum iteration count. Reassess the work factor as server performance and policy requirements change.