常量密码¶
ID: swift/constant-password
Kind: path-problem
Security severity: 6.8
Severity: error
Precision: high
Tags:
- security
- external/cwe/cwe-259
Query suites:
- swift-code-scanning.qls
- swift-security-extended.qls
- swift-security-and-quality.qls
使用硬编码密码推导出基于密码的加密密钥是不安全的,因为生成的密钥很容易被发现。使用常量盐进行哈希处理的数据容易受到字典攻击,攻击者可以恢复原始输入。
特别是,即使存在盐,常量密码也会使密钥更容易恢复。如果盐足够随机,那么密钥恢复就不像在源代码中查找硬编码凭证那样容易。
建议¶
使用随机生成的密码安全地推导出基于密码的加密密钥。
示例¶
以下示例展示了哈希输入数据的几种情况。在“坏”的情况下,密码是常量,这使得推导出的密钥容易受到字典攻击。在“好”的情况下,密码是随机生成的,这可以保护哈希数据免遭恢复。
func encrypt(padding : Padding) {
// ...
// BAD: Using constant passwords for hashing
let password: Array<UInt8> = [0x2a, 0x3a, 0x80, 0x05]
let randomArray = (0..<10).map({ _ in UInt8.random(in: 0...UInt8.max) })
_ = try HKDF(password: password, salt: randomArray, info: randomArray, keyLength: 0, variant: Variant.sha2)
_ = try PKCS5.PBKDF1(password: password, salt: randomArray, iterations: 120120, keyLength: 0)
_ = try PKCS5.PBKDF2(password: password, salt: randomArray, iterations: 120120, keyLength: 0)
_ = try Scrypt(password: password, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1)
// GOOD: Using randomly generated passwords for hashing
let password = (0..<10).map({ _ in UInt8.random(in: 0...UInt8.max) })
let randomArray = (0..<10).map({ _ in UInt8.random(in: 0...UInt8.max) })
_ = try HKDF(password: password, salt: randomArray, info: randomArray, keyLength: 0, variant: Variant.sha2)
_ = try PKCS5.PBKDF1(password: password, salt: randomArray, iterations: 120120, keyLength: 0)
_ = try PKCS5.PBKDF2(password: password, salt: randomArray, iterations: 120120, keyLength: 0)
_ = try Scrypt(password: password, salt: randomArray, dkLen: 64, N: 16384, r: 8, p: 1)
// ...
}
参考资料¶
Okta 博客:什么是带盐密码和密码哈希?
RFC 2898:基于密码的密码学规范.
常见弱点枚举:CWE-259.