説明
パスワードハッシュや鍵導出に固定ソルトを使うと、同じアルゴリズムと設定では、同じ入力が同じ結果になります。攻撃者はパスワード候補の計算結果を複数のユーザーに使い回せます。
想定される影響
- 辞書攻撃に必要な計算コストの低下
- 同じパスワードを使うユーザーの特定
- 流出したハッシュからパスワードを復元される可能性の増加
対処方法
- ユーザーやパスワードごとに、暗号学的に安全な乱数でソルトを生成してください。
- ソルトはハッシュと一緒に保存できますが、コード内の定数にしないでください。
- 確認済みのパスワードハッシュライブラリが提供するソルト生成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)
}
解説:
- 変更前: 全ユーザーで同じソルトを共有すると、計算済みのパスワード候補を使い回されます。
- 変更後: ハッシュごとに新しいランダムなソルトを使い、後の検証に利用できるよう、導出した鍵と一緒に保存します。