会員登録すると
学習することができます。
会員登録する(無料)
登録済みの方はこちら
ログイン

パスワードとログイン試行 ― 後から強くでき、本人を締め出さず、登録の有無を漏らさない

目安学習時間 13分

課題

全問正解でレクチャー完了です。

【問題1】

bcrypt のように「方式とコストが保存した値の中に入っている」形の利点として、この講座が挙げているものはどれですか。

[選択肢]

【問題2】

ログインの失敗を「アカウントごとのロック」だけで防いでいると、どんな困りごとが起きますか。

[選択肢]
会員登録すると
学習することができます。
会員登録する(無料)

学ぶ目的

講座17の先へ

パスワードを平文で保存しない、ハッシュ化する、ソルトを混ぜる、試行回数を制限する。ここまでは講座17で学びました。この回は「その決め方だと、後から何に困るか」を見ます。

方式と強さを、保存した値の中に入れておく

同じパスワードを bcrypt(パスワード保存用のハッシュ方式)で2回ハッシュしてみました(Ruby の bcrypt 3.1.22 で確認)。

$2a$12$8WpTMzTjS9TVaFHhmp/DAObLoKaL0CEKFXQbgEUzc1phEQfYNx3ea
$2a$12$pPHI6iybaoKs4OY7jVIl1OK3Kx4mWbIX2Ztnd.2SNcBoYrKns2GkO

値は毎回違いますが、どちらも元のパスワードで照合が通ります。先頭の $2a$12$ は「方式は 2a、コスト(計算の重さ)は12」という意味です。手元ではコスト12の計算に約0.23秒かかりました。総当たりする側にも、1回ごとにこの重さがかかります。

Rails では has_secure_password を書くと、この bcrypt で保存と照合をしてくれます。

class Account
  include ActiveModel::SecurePassword
  has_secure_password
end
a = Account.new(password: "correct horse")
a.authenticate("wrong")  # => false

naminori の会員と管理者のパスワードも、Devise(Rails のログイン機能の部品)を通して bcrypt で保存しています。

後から困ること:速いハッシュで保存する

SHA-256 を1回かけただけで保存すると、同じパスワードは毎回同じ値になり、計算も一瞬です。漏れたら総当たりが速く進みます。

困るのは、気づいて直そうとしたときです。元のパスワードは誰にも分からないので、全員分を一度に作り直せません。 ログインしてきた人から順に作り直すしかなく、来ない人の値はずっと弱いまま残ります。方式とコストが値に入っている形なら、コストを上げても古い値はそのまま照合でき、ログインのついでに新しい強さへ作り直せます。

試行の制限は2つの単位で

単位 防げること それだけだと困ること
アカウントごと(ロック) 1人を狙った総当たり 他人がわざと間違え続けると、本人が締め出される
アクセス元ごと(回数制限) 1か所からの大量の試行 多くのアカウントに少しずつ試す攻撃は止めにくい

片方だけでは足りないので、両方を使います。ロックを解く手段も最初に決めます。解く手段が「問い合わせ」だけだと、締め出された人の対応で運営が詰まります。メールのリンクで解ける、一定時間たてば解ける、といった手段を用意しておきます。naminori では、アクセス元ごとにログインの試行回数を制限しています。

登録の有無を漏らさない

ログインに失敗したとき「このメールアドレスは登録されていません」と出すと、誰が登録しているかを調べられてしまいます。転職サービスでは、登録していること自体が知られたくない情報です。いまの勤め先に転職活動が知られるかもしれないからです。

naminori のログイン画面は、メールアドレスとパスワードのどちらが違っても同じ文言を返します。

後から困るのは、入口がログイン画面だけではないことです。会員登録の「このアドレスは使われています」、パスワード再設定の「登録がありません」からも同じことが分かります。1か所だけ揃えても、別の画面から漏れます。画面ではいつも同じ応答を返し、詳しいことは登録済みのメールアドレスに送る、という形にしておくと揃えやすくなります。

このレクチャーで学ぶこと

  • bcrypt の値に方式とコストが入っている(手元で確認)
  • 速いハッシュで保存すると、後から強くできない
  • 試行の制限はアカウントごととアクセス元ごとの両方で
  • 登録の有無を、どの入口からも漏らさない

質問

まだ質問は投稿されていません。

質問投稿

ログイン後に質問の投稿ができます。