Swiftでの固定ソルトの使用

Swiftでの固定ソルトの使用

説明

パスワードハッシュや鍵導出に固定ソルトを使うと、同じアルゴリズムと設定では、同じ入力が同じ結果になります。攻撃者はパスワード候補の計算結果を複数のユーザーに使い回せます。

想定される影響

  • 辞書攻撃に必要な計算コストの低下
  • 同じパスワードを使うユーザーの特定
  • 流出したハッシュからパスワードを復元される可能性の増加

対処方法

  1. ユーザーやパスワードごとに、暗号学的に安全な乱数でソルトを生成してください。
  2. ソルトはハッシュと一緒に保存できますが、コード内の定数にしないでください。
  3. 確認済みのパスワードハッシュライブラリが提供するソルト生成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)
}

解説:

  • 変更前: 全ユーザーで同じソルトを共有すると、計算済みのパスワード候補を使い回されます。
  • 変更後: ハッシュごとに新しいランダムなソルトを使い、後の検証に利用できるよう、導出した鍵と一緒に保存します。

参考資料