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

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の使い方
- lockboxの導入
- キーの生成・設定
- 暗号化したい属性のカラム名に
_ciphertext
を追加(例,email_ciphertext
) - 暗号化したい属性を
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"

暗号化する属性(カラム)の追加
秘匿情報を扱うには_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
暗号化・復号化の確認
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つになれば幸いです。