설명
비밀번호 해싱이나 키 유도에서 고정 salt를 사용하면 같은 알고리즘과 설정에서 동일한 입력이 같은 결과로 이어집니다. 공격자는 비밀번호 후보의 계산 결과를 여러 사용자에게 재사용할 수 있습니다.
잠재적 영향
- 사전 공격 비용 감소
- 같은 비밀번호 사용자 식별 가능성 증가
- 유출된 해시의 복구 가능성 증가
해결 방법
- salt는 사용자/비밀번호마다 암호학적으로 안전한 난수로 생성합니다.
- salt는 해시와 함께 저장할 수 있지만 코드에 상수로 고정하지 않습니다.
- 검증된 비밀번호 해싱 라이브러리의 salt 생성 API를 사용하세요. 솔트와 별개로 알고리즘과 작업량도 적절히 설정해야 합니다.
예시
변경 전
swift
try PKCS5.PBKDF2(
password: password,
salt: Array<UInt8>("staticSalt".utf8),
iterations: 600000,
keyLength: 32).calculate()
변경 후
swift
import CryptoSwift
func derivePasswordKey(
password: [UInt8]
) throws -> (salt: [UInt8], derivedKey: [UInt8]) {
let salt = (0..<16).map { _ in UInt8.random(in: 0...UInt8.max) }
let derivedKey = try PKCS5.PBKDF2(
password: password, salt: salt, iterations: 600000, keyLength: 32
).calculate()
return (salt, derivedKey)
}
설명:
- 변경 전: 모든 사용자에게 같은 salt를 사용하면 공격자가 미리 계산한 후보를 재사용할 수 있습니다.
- 변경 후: 각 해시마다 새 난수 salt를 사용하고, 이후 검증에 사용할 수 있도록 파생 키와 함께 salt를 저장합니다.