t_wの輪郭

 私も当初よりハッシュ化したメールアドレスをキーにする方法を考えていたのですが、結論から言うと難しいです。おっしゃる通り、ハッシュ化したメールアドレスをキーにすれば一見問題ないように思えたのですが、以下の理由から低い計算コストで実現するのは難しいと判断しました。

  • メールアドレスをハッシュ化するSALTは値が毎回変わる
  • 「ハッシュ化したメールアドレス」と「メールアドレスをハッシュ化するSALT」のペアは利用者の数だけ存在する
  • そのため、「利用者認証時に入力されたメールアドレス」をハッシュ化する適切なSALTを、O(1)で見つける方法が存在しない
    • 以下の手順を用いれば計算コストO(N)で「利用者認証時に入力されたメールアドレス」をハッシュ化する適切なSALTを見つけることができる
      1. DBから全ての「ハッシュ化したメールアドレス」と「メールアドレスをハッシュ化するSALT」を取り出す
      2. 取り出した全ての「メールアドレスをハッシュ化するSALT」で、入力されたメールアドレスをハッシュ化する
      3. 「DBから取り出したSALTでハッシュ化したメールアドレス」と、「DBから取り出したハッシュ化したメールアドレス」を全て突合する
  • また、利用者登録時にもメールアドレスの重複を検査する必要があるため、『「利用者認証時に入力されたメールアドレス」をハッシュ化する適切なSALTを、O(1)で見つける方法が存在しない』という問題になる

処理の流れ

メールアドレスとパスワードを入力し、利用者を登録する(メールアドレス・パスワードをハッシュ化してDBに保存する)

  1. メールアドレス用のSALTを作成する
    • 作成するたびに値が変わる
    • mailaddress_salt_dbとする
  2. メールアドレスをハッシュ化する
    • mailaddress_hashed_dbとする
  3. パスワード用のSALTを作成する
    • 作成するたびに値が変わる
    • password_salt_dbとする
  4. パスワードをハッシュ化する
    • password_hashed_dbとする
  5. 利用者情報(mailaddress_hashed_db(主キー)、mailaddress_salt_db、password_hashed_db、password_hashed_db)をDBに保存する

メールアドレスとパスワードを入力し、利用者を認証する(メールアドレスでDBに保存したハッシュ化したパスワードを取り出し、入力されたパスワードと照合する)

  1. メールアドレス用のSALTを取得する
    • mailaddress_saltとする
    • ここで不都合が生じる。SALTは生成する度に値が異なる かつ 利用者情報のレコードが複数存在する 場合、DBに保存した際のメールアドレス用のSALTを計算コストO(1)で取得することができない。
  2. メールアドレスをハッシュ化する
  3. ハッシュ化したメールアドレスで利用者情報(ハッシュ化したメールアドレス、メールアドレス用のSALT、ハッシュ化したパスワード(password_hashed_dbとする)、パスワード用のSALT)を取得する
  4. 入力されたパスワードをDBのパスワード用のSALT でハッシュ化する(password_hashedとする)
  5. password_hashed_dbとpassword_hashedが一致していれば認証成功とし、一致していなければ認証失敗とする

あれ

2022/4/21 0:33:00

 メールアドレスもハッシュ化を試してみたところ、問題が一つ発生した。メールアドレスとパスワードによって認証する時、メールアドレスにSALTを付与したうえでハッシュ化しているために、利用者が入力したメールアドレスをキーとして、DBに格納されているハッシュ化したパスワードを引き出すことができない。
 無理やり突合するならば、すべてのSALTを取り出して、ハッシュ化して突合すれば何とかできるが、計算コストがかかってしまう。
 もしくは、メールアドレス以外に主キーにできる値を持たせられればいいが、それを利用者に覚えてもらうというのも現実的ではない。

 良いアイデアだと思ったが、うまくいかないので棄却するしかない。

『PBKDF2 - Wikipedia』

2022/4/20 16:39:00

PBKDF2 (Password-Based Key Derivation Function 2) は、鍵導出関数である。計算コストを変動させることが可能であり、暗号化する際に、総当たり攻撃に対する脆弱性を軽減することを目的として使用される。

PBKDF2は、導出鍵が160ビット以下に制限されるPBKDF1に続いて[1]、PKCS #5 v2.0 (RSA)、RFC2898 (IETF) として規定された。2017年に公開されたRFC 8018 (PKCS #5 v2.1)は、パスワードのハッシュ化には、PBKDF2を利用することを推奨している[2]。