Rails

【Rails】秘匿情報を暗号化し、管理することができるGem「lockbox」の使い方について簡単にまとめてみる

Rails

 

今回は秘匿情報を暗号化した状態で管理することができるGem「lockbox」の使い方について簡単にまとめたいと思います。秘匿情報を扱う際の選択肢の1つになれば幸いです。

類似のGemとしては「attr_encrypted」や「vault-rails」などが挙げられます。

Rails7から属性暗号化機能は標準装備されるようになりました。
Rails
【Rails7】ActiveRecord Encryptionを用いてデータベースの情報を暗号化する方法メモRails7で導入されたデータベースの情報を暗号化する機能「ActiveRecord Encryption」を触ってみたので、その機能について簡単に紹介しています。これまでデータベースの情報を暗号化したい場合は、lockboxやbcrypt-rubyといった外部gemの使用が一般的でしたが、Rails7からはデフォルトでその機能が使えるようになりました。...

lockboxとは

lockboxとは、秘匿情報を暗号化した状態でデータベースに保存することができるGemです。いつも通りデータの代入や呼び出しを行うだけで、暗号化と復号化をlockbox側でよしなに行ってくれます。

📦Modern encryption for Ruby and Rails

・Works with database fields, files, and strings
・Maximizes compatibility with existing code and libraries
・Makes migrating existing data and key rotation easy
・Has zero dependencies and many integrations

📦Railsの最新の暗号化

・データベースのフィールド、ファイル、および文字列を操作
・既存のコードおよびライブラリとの互換性を最大化
・既存のデータの移行とkeyのローテーションが容易
・依存関係がなく、多くの統合関係

参考: ankane/lockbox

(ざっくり解説)lockboxの使い方

  1. lockboxの導入
  2. キーの生成・設定
  3. 暗号化したい属性のカラム名に_ciphertextを追加(例, email_ciphertext
  4. 暗号化したい属性をhas_encryptedの後にモデルに定義(例, has_encrypted :email

lockboxの使い方

gemの導入

gem "lockbox"
% bundle install

Keyの生成

% rails c
> Lockbox.generate_key
=> "0000000000000000000000000000000000000000000000000000000000000000"

キーの設定

生成したキーをcredentialsに設定します。

# VSCodeで開く場合
% EDITOR='code --wait' rails credentials:edit --environment development

# vimエディタで開く場合
% EDITOR=vi bin/rails credentials:edit --environment development
lockbox:
  master_key: "0000000000000000000000000000000000000000000000000000000000000000"
今回は開発環境で動作確認を行うため、development.yml.encのみ生成しています。
Rails
【Rails】秘匿情報を環境毎に管理することができるMulti Environment Credentialsについて初心者向けにまとめてみた今回は秘匿情報を環境毎に管理することができるMulti Environment Credentialsについて簡単にまとめたので紹介しています。付与されている権限によって閲覧できる情報を管理することができるため、権限の異なる複数人で開発する際にはもってこいの機能になります。...

暗号化する属性(カラム)の追加

秘匿情報を扱うには_ciphertextを末尾に付けた属性名(カラム名)にしなければなりません。例えばemailを暗号化したい場合、email_ciphertextという属性名(カラム名)になります。

class AddEmailCiphertextToUsers < ActiveRecord::Migration[7.0]
  def change
    add_column :users, :email_ciphertext, :text
  end
end

モデルの指定

暗号化したい属性をhas_encryptedでモデルに指定します。

class User < ApplicationRecord
  has_encrypted :email
end

 

複数の属性を指定したい場合は、以下のようにつなげて記述することも可能です。

class User < ApplicationRecord
  has_encrypted :email, :phone, :city
end

 

型指定をすることも可能です。

class User < ApplicationRecord
  has_encrypted :birthday, type: :date
  has_encrypted :signed_at, type: :datetime
  has_encrypted :opens_at, type: :time
  has_encrypted :active, type: :boolean
  has_encrypted :salary, type: :integer
  has_encrypted :latitude, type: :float
  has_encrypted :video, type: :binary
  has_encrypted :properties, type: :json
  has_encrypted :settings, type: :hash
  has_encrypted :messages, type: :array
  has_encrypted :ip, type: :inet
end
デフォルトはstring型になります。

暗号化・復号化の確認

User.create!(email: "hi@example.org")

TRANSACTION (1.0ms)  BEGIN
INSERT INTO `users` (`email`) VALUES ('hi@example.org')
TRANSACTION (5.1ms)  COMMIT
=> #<User id: 2, email: [FILTERED]>
User.last.email
=> "hi@example.org"

既存の属性(カラム)を暗号化したい場合

既存の属性を暗号化することも可能です。

まずは_ciphertextを追加したカラムを追加します。

class AddEmailCiphertextToUsers < ActiveRecord::Migration[7.0]
  def change
    add_column :users, :email_ciphertext, :text
  end
end

 

モデルに以下の記述を追加します。

class User < ApplicationRecord
  has_encrypted :email, migrating: true
end

 

コンソール上でデータを挿入します。

% rails c
> Lockbox.migrate(User)

 

以下のようにモデルを再編集します。

class User < ApplicationRecord
  has_encrypted :email

  # remove this line after dropping email column
  self.ignored_columns = ["email"]
end

 

最後に暗号化していないカラムを削除します。

class RemoveEmailFromUsers < ActiveRecord::Migration[7.1]
  def change
    remove_column :users, :email, :string
  end
end

まとめ

  • lockboxとは、秘匿情報を暗号化した状態でデータベースに保存することができるGem
  • 秘匿情報を扱うには_ciphertextを末尾に付けた属性名にしなければならない
  • 暗号化したい属性をhas_encryptedでモデルに指定しなければならない

参考

 

今回は秘匿情報を暗号化した状態で管理することができるGem「lockbox」の使い方について簡単に紹介しました。秘匿情報を扱う際の選択肢の1つになれば幸いです。