Skip to content

Instantly share code, notes, and snippets.

@mori-dev
Created May 11, 2012 11:24

Revisions

  1. mori-dev created this gist May 11, 2012.
    69 changes: 69 additions & 0 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,69 @@
    # attr_encrypted gem でカラムを暗号化する

    ## 特徴

    attr_encrypted gem を使えば、データベースのテーブルの指定したカラムを暗号化できます。次のような特徴があります。

    * 通常の処理はプログラムから暗号化カラムを意識せずに書けます
    * ActiveRecord の find_by_, scoped_by_ メソッドも暗号化カラムを意識せずに使えます
    * 様々な暗号化方式を選択できます


    ## Rails プロジェクトでの導入例

    データベースの users.email の内容を暗号化して管理したい場合の手順を示します。

    Gemfile に以下を追加します。

    gem 'attr_encrypted'

    マイグレーションで users.encrypted_email を作成します。このカラム名は好きな名前で設定できます。

    class AddColToUsers < ActiveRecord::Migration
    def change
    add_column :users, :encrypted_email, :string
    end
    end

    ユニーク制約などは、暗号化されたデータが格納されるカラムに対してかけるように、変更します。

    def up
    change_column_null :users, :email, true
    add_index :users, :email, :unique => false
    change_column_null :users, :encrypted_email, false #true で not_null がはずれる
    add_index :users, :encrypted_email, :unique => true
    end
    def down
    change_column_null :users, :email, false #true で not_null がはずれる
    add_index :users, :email, :unique => true
    change_column_null :users, :encrypted_email, true
    add_index :users, :encrypted_email, :unique => false
    end


    User モデルに以下を追記します。

    attr_encrypted :email, :key => 'secret_key_a'

    *:key の値をどう管理するか* はセキュリティ上重要です。ここではその話題は扱いません。


    ## DBのデータとモデルのオブジェクトの扱い

    users テーブルに新規レコードを追加すると、users.encrypted_email に暗号化されたデータが格納されます。users.email には何も格納されません。
    User モデルのオブジェクトを取得すると :email には、登録したメールアドレスが格納されています。

    #<User:0x00000104949210> {
    :id => 4,
    :username => taro,
    :email => "[email protected]",
    :created_at => Fri, 11 May 2012 07:45:48 UTC +00:00,
    :updated_at => Fri, 11 May 2012 07:45:48 UTC +00:00,
    :encrypted_email => "yFRH70SW6ztrl9nuqF6v3VtK5fC/khIddOsEAgDmw=\n"
    },

    rais console からも取得 *できます*

    1.9.3-p125-perf :005 > u = User.find(4)
    1.9.3-p125-perf :006 > u.email
    => "[email protected]"