Rails – パスワードの暗号化~ゼロから

概要

パスワードをデータベースに保存する際に暗号化して、万一流出した際のリスクを減らす方法。ここではハッシュ化してメッセージダイジェストにすることを「暗号化」とする。

暗号化されたパスワードを保存しておき、サインインの際に入力されたパスワードを同じ手順で暗号化し、得られたメッセージダイジェストが一致すれば符合しているとする。

以下の方法で順次リスクを減らしていく。

  1. パスワードをハッシュ化
  2. パスワードにソルトを連結してハッシュ化
  3. パスワードとソルトをそれぞれハッシュ化したものを連結してハッシュ化
  4. より安全性の高いハッシュ化を適用

ここでは3つ目の方法でRailsのDigest::MD5を使った手順を整理。

手順

パスワードを与える。

password = "pass"

ソルトを準備する。

salt = "SdvLigVDW3iDtHGAYvccBSbDn+jl"

パスワードとソルトを連結した文字列を暗号化する。

Digest::MD5.hexdigest(pass_digest + salt_digest)

この結果、以下のメッセージダイジェストが得られる。

"d1d7bd4a8d1e0a3be09d701db50ec038"

パスワードをpass→sassにしたときのメッセージダイジェストは以下の通り。

"82035cbcc496621133b8773709285313"

モデルへの実装

Railsでモデルを介してデータベースに登録する場合、モデルに暗号化の処理を書く。たとえばUserモデルのpasswordを暗号化する場合の例は以下の通り。

before_createでコールバックを設定していて、データベースへの書き込み前にencrypt_passwordメソッドが呼ばれる。

これをbefore_saveで呼ぶとデータ更新のときにもパスワードがハッシュ化されてしまうので、データの新規作成のときだけ呼ばれるようbefore_createで呼ばなければんならない。

encrypt_passwordはクラスメソッドのpassword_digestpasswordをメッセージダイジェストに変換し、その値でpasswordを書き換える。

password_digestメソッドは、パスワードとソルトからメッセージダイジェストを返す。

その結果、データベースへの書き込み時には暗号化されたパスワードが保存される。

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です