web-dev-qa-db-ja.com

リクエストごとにユーザー名/パスワードの代わりに認証トークンを使用するのはなぜですか?

https://stackoverflow.com/a/477578/14731 の作成者は次のことを推奨しています。

永続的なログインクッキー(トークン)をデータベースに保存しないでください。 [...]永続的なログイントークンを保存するときに、強力なソルトハッシュ(bcrypt/phpass)を使用します。

ログインCookieには2つの目的があるという印象を受けました。

  1. UXのメリット:リクエストごとに1回ログインするようユーザーに要求しない
  2. パフォーマンス上の利点:リクエストごとに低速のアルゴリズム(bcryptなど)を実行する必要がない

作者が2番目のポイントを無効にしているようです。そのため、なぜ認証トークンに煩わされるのでしょうか。ユーザー名/パスワードをランダムに選択した認証トークンにマッピングする代わりに、httpOnlysecure cookieを使用して、リクエストごとにユーザー名/パスワードを単純に渡さないのはなぜですか?

著者の推奨を受け入れ、リクエストごとにbcryptを使用すると仮定すると、ユーザー名/パスワードの代わりに認証トークンを使用する利点は何ですか?

45
Gili

「認証トークン」を使用する場合、クライアントがそのトークンを提示するだけでアクセスが許可されます(トークンがサーバーによって有効であると見なされる限り)。トークンを「そのまま」サーバーのデータベースに保存すると、データベースを垣間見ることができる攻撃者はすべてのトークンをすぐに学習し、有効なトークンがまだ存在するすべてのユーザーの名前でリクエストを送信できるようになります。データベース内。これは悪いです。したがって、認証トークンのハッシュのみを保存することをお勧めします。

Bcryptに関するアドバイス認証トークンの場合は誤った説明です。 Bcryptは パスワードハッシュ 専用のすべての関数と同様に、passwordsで使用するためのものです。パスワードは脆弱です。それらは辞書攻撃に対して脆弱です。それらの固有の弱点に対処するために、パスワードハッシュ関数はソルト(並列攻撃と事前計算されたテーブルを防止する)である必要があり、また(内部反復の場合は膨大な数になるため)非常に低速でなければなりません。これにより、パスワードハッシュ関数高価になります。したがって、必要な場合を除いて、パスワードハッシュ関数を使用したくありません。パスワードをハッシュ化する。

認証トークンはパスワードではありません。これはランダムな値であり、人間の脳がプロセスに関与することなく、コンピューターによって生成および記憶されます。そのため、トークンを適切に生成した場合(少なくとも128ビット、 (暗号学的に安全なPRNG から取得))、ソルトや反復の必要はありません。単純なハッシュ関数を使用するだけです(MD5でも問題ありません)。これはより効率的です。

リクエストごとにlogin + passwordの代わりにランダム認証トークンを使用する場合、その理由は主に2つあります。

  1. パフォーマンス:上で説明したように、認証トークンは単純なハッシュで安全に検証できます。これは、重いbcrypt呼び出しよりもはるかに効率的です。特にbcryptを実際に人間が管理するパスワードに適用するときに、貴重なCPUサイクルをそれらが本当に役立つときのために保持したいとします。

  2. クライアント側のストレージ:認証トークンはcookie値としてクライアントに保存されます。ログインとパスワードがすべてのリクエストで返される場合、それらはクライアントのCookieとして保存されます。パスワードがファイルに書き込まれると人々は緊張します-そのようなストレージは(セキュリティの観点から)認証トークンのストレージと同等ではありません。人間のユーザーは複数のパスワードを再利用する(悪い)癖があるためです。一方、認証トークンは本質的にサーバー固有のものです。

67
Thomas Pornin