67
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

Railsでデータを可逆暗号で保存する

Railsで、ユーザを作って、ユーザのパスワードを可逆暗号で暗号化してから保存します。

環境

  • Ubuntu 14.10
  • Ruby 2.1.5
  • Rails 4.2

ユーザテーブルの作成

ユーザテーブルのカラムは、ユーザー名の name:string とパスワードの password:string です。

rails generate scaffold user name:string password:string

カラムを空で保存したくないので、マイグレーションファイルを少し書き変えます。

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name, null: false
      t.string :password, null: false

      t.timestamps null: false
    end
  end
end

そして、rake db:migrate します。

検証の追加

ユーザモデルに検証を追加します。
とりあえず、user カラムと password カラムは空でなく、さらにユニークであるという検証を追加しました。
この時、フォームが空だったら uniqueness の検証はスキップするようにしてます。

user.rb
class User < ActiveRecord::Base
  # userカラムとpasswordカラムは空でなくユニークである
  validates :name, :password,
            presence: true,
            uniqueness: { allow_blank: true }
end

passwordカラムの暗号化

暗号化は、データの保存前におこない
暗号化には、ActiveSupport::MessageEncryptor を利用します。
ちなみに、暗号化には標準添付ライブラリの OpenSSL を使っているので、ライブラリに対応した暗号化方式を CIPHER で指定したら好きな暗号化方式を選べます。

モデルを変更

user.rb
class User < ActiveRecord::Base
  # userカラムとpasswordカラムは空でなくユニークである
  validates :name, :password,
            presence: true,
            uniqueness: { allow_blank: true }

  before_save :encrypt_password

  def encrypt_password
    self.password = encrypt(self.password)
  end

  # SECUREは短いとエラーを吐く
  SECURE = 'HOGEHOGEHOGEHOGEHOGEHOGEHOGEHOGEHOGEHOGEHOGEHOGEHOGE'
  CIPHER = 'aes-256-cbc'

  # 暗号化
  def encrypt(password)
    crypt = ActiveSupport::MessageEncryptor.new(SECURE, CIPHER)
    crypt.encrypt_and_sign(password)
  end

  # 復号化
  def decrypt(password)
    crypt = ActiveSupport::MessageEncryptor.new(SECURE, CIPHER)
    crypt.decrypt_and_verify(password)
  end
end

暗号化する encrypt メソッドを定義し、コールバックを使用して、データの保存前に実行するようにしました。
さらに、復号化する decrypt メソッドも定義しました。
実際に使用するときは、SECURECIPHER は適切な場所に定数として定義した方がいいです。

これで、パスワードが暗号化されて保存されます。

確認

実際に暗号化されているか確認します。

rails sでサーバを起動したら、http://localhost:3000/users/newにアクセスします。

そしてフォームに値を入力してサブミットしたら、コマンド rails dbconsole を実行して select * from users;を実行すると、暗号化の確認をすることができます。

終わりに

ActiveSupportには、便利なライブラリがたくさんあることを再確認できた。

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
67
Help us understand the problem. What are the problem?