在密码上使用不合适的加密哈希算法¶
ID: swift/weak-password-hashing
Kind: path-problem
Security severity: 7.5
Severity: warning
Precision: high
Tags:
- security
- external/cwe/cwe-327
- external/cwe/cwe-328
- external/cwe/cwe-916
Query suites:
- swift-code-scanning.qls
- swift-security-extended.qls
- swift-security-and-quality.qls
计算强度不足的哈希函数会导致数据易受攻击。您不应该将此类函数用于密码哈希。
强大的加密哈希函数应该能够抵抗
原像攻击。如果您知道哈希值
h(x)
,您不应该能够轻松找到输入x
。碰撞攻击。如果您知道哈希值
h(x)
,您不应该能够轻松找到一个不同的输入y
,它具有相同的哈希值h(x) = h(y)
。暴力破解。如果您知道哈希值
h(x)
,您不应该能够找到一个输入y
,它使用暴力破解攻击计算到该哈希值,而无需大量的计算量。MD5、SHA-1、SHA-2 和 SHA-3 都容易受到离线暴力破解的攻击,因为它们的计算强度不足。这包括 SHA-224、SHA-256、SHA-384 和 SHA-512,它们属于 SHA-2 家族。
密码哈希算法应该计算缓慢或内存密集,以使暴力破解攻击更加困难。
建议¶
对于密码存储,您应该使用计算强度足够的加密哈希函数,例如以下函数之一
Argon2
scrypt
bcrypt
PBKDF2
示例¶
以下示例显示了同一个函数的两个版本。在这两种情况下,密码都使用加密哈希算法进行哈希处理。在第一种情况下,使用了 SHA-512 哈希算法。它容易受到离线暴力破解攻击
let passwordData = Data(passwordString.utf8)
let passwordHash = Crypto.SHA512.hash(data: passwordData) // BAD: SHA-512 is not suitable for password hashing.
// ...
if Crypto.SHA512.hash(data: Data(passwordString.utf8)) == passwordHash {
// ...
}
以下是用 Argon2 的相同函数,该函数适合用于密码哈希
import Argon2Swift
let salt = Salt.newSalt()
let result = try! Argon2Swift.hashPasswordString(password: passwordString, salt: salt) // GOOD: Argon2 is suitable for password hashing.
let passwordHash = result.encodedString()
// ...
if try! Argon2Swift.verifyHashString(password: passwordString, hash: passwordHash) {
// ...
}
参考资料¶
OWASP: 密码存储备忘单
GitHub: CryptoSwift README - 基于密码的密钥派生函数
libsodium: 适用于其他语言的 libsodium 绑定
GitHub: Argon2Swift
常见弱点枚举:CWE-327.
常见弱点枚举:CWE-328.
常见弱点枚举:CWE-916.