LoginSignup
8
2

More than 3 years have passed since last update.

attr_encryptedなカラムを検索する方法

Last updated at Posted at 2019-10-07

初めまして、ガッシーです。Qiita初投稿となります。(なんか癖でQuiitaって打っちゃうんですよね)
日頃Railsの開発で躓いて調べたことなどを書き留めていければなと思ってます。
そんなところで本題へ。

railsでカラムを暗号化する際には一般的にattr_encryptedを利用するかと思いますが
READMEを翻訳しますと 

暗号化されたデータを検索することはできません。検索できないため、インデックスを作成することもできません。

との記載があります。
でも暗号化しつつ検索したいことって結構あると思うんですよね。

そこで登場するGemがblind_indexです。
ただし LIKE検索はできない ので注意してください。

blind_indexとは

例えばnameというカラムでattr_encryptedを使うときは encrypted_nameencrypted_name_iv の2つのカラムを用意すると思いますが、
それに加えて encrypted_name_bidx というカラムを追加してあげることで、そこに検索できる値を保存する感じです。早速やってみましょう。

設定

READMEに書いてあることをそのままやっていけばいいのですが一応書きます。
Gemfileに下記を追加してbundle install

gem 'blind_index'

コンソールを起動して下記コードを実行しランダムなキーを取得します。

irb(main):001:0> BlindIndex.generate_key
# SecureRandom.hex(32).force_encoding(Encoding::US_ASCII) でも同じ
=> "222189cbba7ba0381c66faf8f687197b4bd4256a99bf81c917256c2871ca5289"

キーを保存・設定します。

credentials.yml.enc
blind_index_master_key: "222189cbba7ba0381c66faf8f687197b4bd4256a99bf81c917256c2871ca5289"
config/initializers/blind_index.rb
BlindIndex.master_key = Rails.application.credentials.blind_index_master_key

(initializerを読み込むためサーバーは再起動しておいてください)

blind_index用のカラムを追加します。

db/migrate/add_name_bidx_to_users.rb
add_column :users, :encrypted_name_bidx, :string

modelも変更を加えます。

app/models/user.rb
class User < ApplicationRecord
  attr_encrypted :name, key: Rails.application.credentials.encrypted_key
  blind_index :name, key: Rails.application.credentials.blind_index_master_key #←こちら追加
end

以上で設定は完了です!

※既に暗号化カラムが保存されている方はコンソールにて下記コマンドを実行することで既存のレコードにも対応できます。

User.unscoped.where(encrypted_name_bidx: nil).find_each do |user|
  user.compute_name_bidx
  user.save(validate: false)
end

実行

User.where(name: "山田太郎")

これができるようになっているはずです。

感想

完全一致検索しかできないけど何もできないよりはマシか・・・
知識がないのですが、最初こちらの記事 attr_encryptedされたカラムに対してwhere likeしたかった。を見ましたが恐らく現在ivカラムを利用した暗号化を行っている場合は適応できないかな?と思ってます。
Qiita初めての記事となりましたのでもし誤りがありましたらご指摘いただければ幸いです。

8
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2