後期第04回 - oddmutou/jugyo-2025kyototech GitHub Wiki
復習
会員登録/ログイン機能について...
この授業でやること
- パスワードの暗号化を独自実装してみる
- 実際の業務でPHP使う際は独自実装せず
password_hash()password_verify()を使いますが、勉強がてら独自実装
- 実際の業務でPHP使う際は独自実装せず
- いろいろなやりかたを試してみる
- DBのデータは都度DELETEして作り直す
暗号化してみましょう。
ハッシュ
ハッシュ関数を使ってパスワードを暗号化します。
ハッシュ関数についておそらく今まで習ったことがあると思いますが、…。
ハッシュ関数は、入力値(引数)を元に、特定の値を出力します。その出力値から入力値に戻すことは基本的に不可能です。
例え話として、じゃがいもをハッシュドポテトにすることは可能ですが、ハッシュドポテトを元のじゃがいもに戻すことは不可能なことと同じです。
そんなハッシュ関数ですが、同じ入力値から得られる出力値は同じです。たとえば 今日はいい天気ですね という文字列を、MD5というアルゴリズムでハッシュ化すると、2bdcaba57608b9e64484dadc72f01ebc という文字列を得ることができます。ハッシュ化して得ることができた値をハッシュ値と呼びます。
これはいつ、どこで、だれがMD5を使ってハッシュ化しても同じです。たとえ100年後にブラジルで宇宙人がおこなったとしても、今日はいい天気ですね から 2bdcaba57608b9e64484dadc72f01ebc というハッシュ値を得ることができます。
echo "今日はいい天気ですね" | md5sum
また、この性質はMD5だけではなく、すべてのハッシュ用アルゴリズムでも同じです。
この性質を用い、生のパスワードを保存せずハッシュ化したパスワードを保存することができます。
ハッシュ値とハッシュ値が等しければ、それぞれの入力も等しいと言うことができます。つまりログイン時には「ログインフォームから入力されたパスワードのハッシュ値」と、「データベースに登録されているパスワードのハッシュ値」を比べれば、パスワードが合っているか確認できる、ということです。
実際にユーザーが入力しているパスワードを保存せず、ハッシュ値のみをデータベース保存することによって、不慮の事故でデータベースの中身が流出し、パスワードのハッシュ値は流出したとしても、生のパスワードは流出しない、とすることができるのです。
ハッシュ化してパスワードを保存してみる実装
前回の授業で作った会員登録/ログイン機能を改修し、ハッシュ化してパスワードを保存するようにしましょう。
先程の説明で例に上げたアルゴリズム MD5 や、 他にも SHA-1 といった古いアルゴリズムは残念ながら現在は脆弱性が見つかっており、安全ではないので使わないようにしましょう。SHA-2 の種類の一つ、sha256 を使っていきます。
まずはじめに、既存の会員データを消します。パスワードの保存方式・認証方式が変わっても古いデータをそのままにしておくと壊れますよね。
mysqlコンテナ内でmysqlクライアントを立ち上げて…
DELETE FROM users;
登録時にパスワードをハッシュ化します。
vim public/signup.php
内容: https://github.com/oddmutou/jugyo-2025kyototech/commit/1850384c55c949d9d45cc766fb0326f2b0ec204a
ログイン時にログインフォームから送られたパスワードもハッシュ化した上でチェックするようにします。
vim public/login.php
中身: https://github.com/oddmutou/jugyo-2025kyototech/commit/38dca856c5c8fda25b186fdc634af99f55173b57
演習
演習1 ソルト
あらゆる入力値に対して計算し出力値をまとめた表、「レインボーテーブル」を用いて、出力値から入力値を求める、つまりハッシュ値からパスワードを導き出す手法があります。とてつもなく大きなテーブルに思えますが、現代のコンピュータのハッシュ計算速度はかなり早く、現実的な時間でテーブルを作り出し、パスワードが攻撃者に漏洩してしまうのです。
そこで、パスワード毎にランダムで生成した値を結合した上でハッシュ化する、という手法を取ることが多いです。そのランダムな値をソルトと良い、ソルト化、と呼んだりします。そのソルトはパスワードのチェック時(=ログイン時)にも使うため、ハッシュ値と一緒に保存しましょう。
今回は演習として、64文字の安全なソルトを生成し、パスワードの後ろにつけて、ハッシュ化するようにしてみてください。ソルトは、ハッシュ値の後ろにくっつけて(文字列結合して)、usersテーブルのpasswordカラムに一緒に保存しましょう。
登録画面とログイン画面の両方を改修しましょう。
実装例: https://github.com/oddmutou/jugyo-2025kyototech/commit/463f1e2be7a4c15c00688bce8f8c28ebcc8ee18b
演習2 ストレッチング
ストレッチング を実装してみましょう。ストレッチング回数は10万回としてください。
参考: https://wa3.i-3-i.info/word16975.html
実装例: https://github.com/oddmutou/jugyo-2025kyototech/commit/1ca925c6bf9ec0683b8a2d64dafbc7fcc400842f