Security
自分用メモ

ログイン機能の実装について、おおまかな仕組み

More than 1 year has passed since last update.

ログイン機能の実装について、おおまかな仕組み

はじめに

ログイン機能を自前のWebアプリに実装するときに、必要になる要素技術を自分用にまとめようかと思う。コードやハウツーではなく、どの機能にどのような理論が必要になるか、など、実装以前の内容を自分用にまとめようかと思う。あくまで自分用にである。大事なことなので3回言いました。

何がしたいか

そこまで本気ではないが、ある程度のセキュリティで、自分のページにくるユーザがログインして、ログイン状態を維持したまま、継続的にサービスを利用できるようにしたい。

ユーザのする作業の流れ

ユーザのする作業の流れ。

  1. アカウント作成ページにアクセスする
  2. アカウント名とメールアドレス、それと、パスワードを入力する。 それと、CAPTCHAを入力する
  3. メールを受信する
  4. メールのなかのアドレスをクリックする、 あるいは、メールで教えられた文字列を専用のページに入力する
  5. 登録完了
  6. ログインページにアカウント名とパスワードを入力する

使用する理論や技術

  • 一方向ハッシュ関数
  • クッキー
  • UUID
  • TLS(HTTPS)
  • GoogleのreCAPTCHA
  • DropBoxのパスワードチェッカー(zxcvbn)
  • データベース
  • passwdフォーマット

前提

  • 当然、接続はHTTPSのみとする。できればHSTSを利用する
  • ここでの「ランダム」は暗号学的なランダムとする。 OSの/dev/urandomあたりの使用を検討

サーバ側の動作の流れ

アカウント作成(サインアップ)

  1. アカウント作成ページでCAPTCHAを提示する
  2. アカウント作成ページではユーザのパスワードの強度を監視する
  3. アカウント作成ページからのユーザの入力を受けとる
  4. CAPTCHAをチェックする
  5. アカウント名の重復をチェックする(データベースへのアクセス)
  6. メールアドレスの重復をチェックする
  7. ソルトをランダムに生成する(20文字くらいか?)
  8. パスワードにソルトをつけたものの ハッシュ(ストレッチングが必要1000回くらい?)を生成する
  9. アカウント名とソルトとハッシュを保存する(データベースへ)
  10. そのとき、アクチベートフラグを偽としておく
  11. ランダムなUUIDと、それを含むアクチベート用アドレスをメールで送信する
  12. ユーザはアクチベート用アドレスをクリックするか、 専用のページにUUIDを入力する
  13. アクチベート用のUUIDが正しければアクチベートフラグを真にする
  14. 30分ごとにチェックして、 アクチベートフラグが偽のものは偽偽として、 偽偽のものはテーブルから削除する

ログイン

  1. ログインページの入力を受けとる
  2. アカウント名からソルトとハッシュを検索
  3. 入力されたパスワードとソルトからハッシュを生成する
  4. 2つのハッシュが一致すれば、ランダムにUUIDを生成し、 アカウント名とUUIDとをデータベースに保管する
  5. UUIDをクッキーに保存させる
  6. このとき、クッキーが他のサイトから見られないような設定にする

ログイン状態

  1. クッキーにUUIDがあれば、それを使ってデータベースから アカウント名を検索する
  2. UUIDは毎日0時に削除候補とする。削除候補は削除する

こんな感じ

こんな感じでログイン機能はつけられるかと思う。セキュリティ的にも大きな問題はないかと思うが、もうすこし調べてみよう。セキュリティ的な問題や、その他運用上に問題があったら、修正する予定。

補足

あまり、多人数の使用が予想されないのであれば、アカウント名、ソルト、ハッシュについては、passwdフォーマットでバックアップをとっておいたほうがいいかもしれない。システムを変更するときに、持ち運びたいだろうから。

安全性の確認

上記の仕組みが安全であることを、ざっくりと確認してみる。

大量のアカウント取得への防御

  • キャプチャによって、あるていどは避けることが可能。
  • ひとりの人がアカウントを多数取得してしまうことは 有効なメールアドレスが必要であることで、 あるていど回避できる

パスワードの漏洩について

  • HTTPSなので、(適切に運用されていれば)通信中の漏洩の可能性は 無視できるくらいに低い
  • サーバ側からの漏洩については、 メモリからの漏洩とハードディスクからの漏洩に分けられる
  • メモリからの漏洩については、 ふつうの高級言語を使っていれば可能性は低い (C言語を使っているとありえる。Heartbleedなど)
  • ハードディスクからの漏洩については、 ソルトを使ってハッシュ化しているので、 パスワードが適切なものであれば、 予測される可能性は低い
  • パスワードが適切でない可能性は、 アカウント作成時のJavascriptによる監視で、 多少は低くできるだろう

クッキーのUUIDの漏洩・予測について

  • HTTPSなので、通信中の漏洩の可能性は低い
  • 他のサイトからクッキーがのぞけないようにする必要がある
  • 暗号学的なランダム値を使っていればUUIDを予測することは困難

そのほか

そのほかにもセキュリティ上、考慮する必要があることはあるか。思いつきしだい追加する予定。

また、セキュリティ上、または、その他、運用上注意する必要がある事柄がありましたら、コメントしていただけると、ありがたいです。