web-dev-qa-db-ja.com

laravelのDBフィールドを暗号化/復号化する

私はLaravelのDBフィールド値をアクセサーとミューテーターを介して暗号化/復号化しています。これは通常の雄弁なトランザクションで正常に機能しています。

class Person extends Model
{
    use Notifiable;
    protected $table = 'person';

    public function getFirstNameAttribute($value)
    {
        return Crypt::decryptString($value);
    }
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $guarded = array();

    protected function user()
    {
        return $this->belongsTo('App\Models\User', 'useraccount_id', 'id');
    }
}

ただし、次の条件下では暗号化と復号化が機能しません

  1. 雄弁な関係
  2. DB生クエリ

ワーキング

$person = Person::find($person_id);
$person->firstName;

動かない

$user = User::find($user_id);
$user->person->firstName;
8
Kalyana Kannan

おそらく、データベースレベルで暗号化を行うことになります。まるで、誰かがデータベースにアクセスしたとしても、人々の医療データをプレーンテキストで読み取ってほしくないのです。

保存および取得時にそれぞれデータを暗号化および復号化する特性を作成できます。

namespace App\Traits;

use Illuminate\Support\Facades\Crypt;
trait Encryptable
{
    /**
     * If the attribute is in the encryptable array
     * then decrypt it.
     *
     * @param  $key
     *
     * @return $value
     */
    public function getAttribute($key)
    {
        $value = parent::getAttribute($key);
        if (in_array($key, $this->encryptable) && $value !== '') {
            $value = decrypt($value);
        }
        return $value;
    }
    /**
     * If the attribute is in the encryptable array
     * then encrypt it.
     *
     * @param $key
     * @param $value
     */
    public function setAttribute($key, $value)
    {
        if (in_array($key, $this->encryptable)) {
            $value = encrypt($value);
        }
        return parent::setAttribute($key, $value);
    }
    /**
     * When need to make sure that we iterate through
     * all the keys.
     *
     * @return array
     */
    public function attributesToArray()
    {
        $attributes = parent::attributesToArray();
        foreach ($this->encryptable as $key) {
            if (isset($attributes[$key])) {
                $attributes[$key] = decrypt($attributes[$key]);
            }
        }
        return $attributes;
    }
}

次に、その特性をモデルに適用し、データを暗号化する必要がある列の配列である$ encryptableというプロパティを定義します。

class YourModelextends Model
{
    use Encryptable;

    protected $encryptable = [
        'code',
        'keys',
        'allergies'
    ];
}
9
iman

LaravelのCryptファサードでそれを行うことができます。この例に従ってください。

use Illuminate\Support\Facades\Crypt;

$encrypted = Crypt::encryptString('Hello world.');

$decrypted = Crypt::decryptString($encrypted);

私はこの記事のリンクから実装しました: https://hackthestuff.com/article/laravel6-encryption-and-decryption-model-data-using-crypt-class

2
Harsukh Makwana

Imanの彼の答えに基づいて、Laravel selfからのキャスト配列で動作するように特性を変更しました。

<?php
namespace App\Library\Traits;

use Illuminate\Support\Facades\Crypt;
trait Encryptable
{
    /**
     * If the attribute is in the encryptable array
     * then decrypt it.
     *
     * @param  $key
     *
     * @return $value
     */
    public function getAttribute($key)
    {
        $value = parent::getAttribute($key);

        if (isset($this->casts[$key]) && $value !== '' && !is_null($value) && $this->casts[$key] == 'encrypt') {
            $value = decrypt($value);
        }
        return $value;
    }
    /**
     * If the attribute is in the encryptable array
     * then encrypt it.
     *
     * @param $key
     * @param $value
     */
    public function setAttribute($key, $value)
    {
        if (isset($this->casts[$key]) && $value !== '' && !is_null($value) && $this->casts[$key] == 'encrypt') {
            $value = encrypt($value);
        }
        return parent::setAttribute($key, $value);
    }
    /**
     * When need to make sure that we iterate through
     * all the keys.
     *
     * @return array
     */
    public function attributesToArray()
    {
        $attributes = parent::attributesToArray();
        foreach ($this->casts as $key => $value) {
            if($value == 'encrypt') {
                if (isset($attributes[$key]) && $attributes[$key] !== '' && !is_null($attributes[$key])) {
                    $attributes[$key] = decrypt($attributes[$key]);
                }
            }
        }
        return $attributes;
    }
}
2
Lennart