サイトアイコン IT NEWS

Laravelで自動的に暗号化してDB保存、復号化して取得する方法

laravel-encrypt

今回は、Laravelデータベース登録時に常に暗号化して、表示する際は必ず復号化する方法をご紹介します。
以前、Laravelトレイトを使って特定のフィールドに自動登録した話の応用になります。
特に個人情報パスワードなどの重要なデータを取り扱う場合には非常に有効で、セキュリティの向上にも繋がりますので、覚えていて損はないかと思います。

自動で暗号化&復号化

今回の目的は、対象のフィールドを指定するだけで、Laravel開発者が特に意識せずに自動暗号化復号化できるようにしたいと思います。
使用するのは、新規で作成するトレイトと既存のモデルのみです。

暗号化&復号化トレイトを作成する

データベース登録前にモデルをセットする際に暗号化し、取得する際に復号化するため、getAttributesetAttributeを上書きします。

app¥Encryptable.php

<?php
namespace App;

use Crypt;

trait Encryptable
{
    public function getAttribute($key)
    {
        $value = parent::getAttribute($key);
        if (in_array($key, $this->encryptable)) {
            $value = Crypt::decrypt($value);
            return $value;
        }
        return $value;
    }

    public function setAttribute($key, $value)
    {
        if (in_array($key, $this->encryptable)) {
            $value = Crypt::encrypt($value);
        }
        return parent::setAttribute($key, $value);
    }
}

モデル内でフィールドを指定

使い方はとっても簡単です。
使用するモデルに先ほど作成したトレイトuseして、$encryptableに配列でフィールド名を書くだけで、暗号化復号化が実現できます。
以下は、ユーザーのプロフィールを暗号化する場合の例です。

例)app¥Profile.php

<?php
namespace App;

use IlluminateDatabaseEloquentModel;
use AppEncryptable;

class Profile extends Model
{
    use Encryptable;
    …
    /**
     * Attributes that should be encryptable.
     *
     * @var array
     */
    public $encryptable = [
        'tel',
        'birth',
        'address',
    ];
}

これで完成です。
一つだけ使用上の注意点として、暗号化されれば保存する文字列が長くなりますので、テーブルを作成する際には格納するフィールドの型に気をつけてください。

暗号化されるとどうなる?

上記の方法で保存したデータは、ランダムな英数記号暗号化され、データベースに格納されます。
Laravelデフォルトのログイン機能のパスワードのように保存されます。
そうなると、万が一データベースからデータを盗まれたとしても、解析できないというわけです。

復号化するには、ユーザーがログインしている状態、かつ、復号キーがないと複号化できないので、セキュリティ的に2重にも3重にもなり、より強固になります。

モバイルバージョンを終了