toolman/laravel-postgresql-encrypted-model 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

toolman/laravel-postgresql-encrypted-model

最新稳定版本:v1.0.1

Composer 安装命令:

composer require toolman/laravel-postgresql-encrypted-model

包简介

A Laravel trait for handling encrypted data in PostgreSQL with configurable encryption algorithms, modes, and comprehensive query methods

README 文档

README

Latest Version on Packagist Total Downloads

A Laravel trait for handling encrypted data in PostgreSQL with configurable encryption algorithms, modes, and comprehensive query methods.

Features

  • Automatic Encryption/Decryption: Automatically handles encryption on save and decryption on retrieval
  • Rich Query Methods: Provides multiple encrypted data query methods (whereCrypted, whereCryptedIn, whereCryptedNot, etc.)
  • Configurable Encryption: Support for custom encryption algorithms, modes, and padding
  • Batch Operations: Support for batch encrypted data updates
  • Security: Uses PostgreSQL's built-in encrypt/decrypt functions for data security

Requirements

  • PHP 8.1 or higher
  • Laravel 9.0, 10.0, or 11.0
  • PostgreSQL with pgcrypto extension enabled

Installation

You can install the package via composer:

composer require toolman/laravel-postgresql-encrypted-model

Enable PostgreSQL pgcrypto Extension

Make sure the pgcrypto extension is enabled in your PostgreSQL database:

CREATE EXTENSION IF NOT EXISTS pgcrypto;

Environment Configuration

Add the following environment variables to your .env file:

DB_ENCRYPTION_KEY=your_secret_encryption_key_here
DB_ENCRYPTION_ALGORITHM=aes
DB_ENCRYPTION_MODE=cbc
DB_ENCRYPTION_PADDING=pkcs

Publish Configuration (Optional)

You can publish the configuration file:

php artisan vendor:publish --provider="Toolman\LaravelPostgresqlEncryptedModel\PostgreEncryptedModelServiceProvider" --tag="config"

Usage

Basic Setup

Use the trait in your Eloquent model and define the encrypted fields:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Toolman\LaravelPostgresqlEncryptedModel\PostgreEncryptedModel;

class User extends Model
{
    use PostgreEncryptedModel;

    protected $fillable = [
        'name',
        'email',
        'phone',
        'address',
        'social_security_number',
    ];

    /**
     * Define which fields should be encrypted
     */
    protected $encryptedFields = [
        'phone',
        'address', 
        'social_security_number'
    ];

    /**
     * Optional: Custom encryption settings
     */
    protected $encryptionAlgorithm = 'aes';  // aes, des, 3des, cast5, blowfish
    protected $encryptionMode = 'cbc';       // cbc, ecb, cfb, ofb
    protected $encryptionPadding = 'pkcs';   // pkcs, none

    protected static function boot()
    {
        parent::boot();
        
        static::creating(function ($model) {
            $model->initializePostgreEncryptedModel();
        });
    }
}

Database Migration

Ensure encrypted fields use appropriate data types (recommend text or bytea):

Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email')->unique();
    $table->text('phone'); // Encrypted field
    $table->text('address'); // Encrypted field
    $table->text('social_security_number'); // Encrypted field
    $table->timestamps();
});

Basic CRUD Operations

// Create - automatic encryption
$user = User::create([
    'name' => 'John Doe',
    'email' => 'john@example.com',
    'phone' => '0912345678', // Will be encrypted
    'address' => 'Taipei, Taiwan', // Will be encrypted
    'social_security_number' => 'A123456789' // Will be encrypted
]);

// Read - automatic decryption
echo $user->phone; // Output: 0912345678 (decrypted)
echo $user->address; // Output: Taipei, Taiwan (decrypted)

Encrypted Query Methods

// Basic queries
$users = User::whereCrypted('phone', '=', '0912345678')->get();
$users = User::whereCrypted('address', 'LIKE', '%Taipei%')->get();

// IN queries
$phones = ['0912345678', '0987654321', '0911111111'];
$users = User::whereCryptedIn('phone', $phones)->get();

// NOT IN queries
$users = User::whereCryptedNotIn('phone', $phones)->get();

// NOT queries
$users = User::whereCryptedNot('address', 'LIKE', '%Taipei%')->get();

// BETWEEN queries
$users = User::whereCryptedBetween('social_security_number', 'A100000000', 'A999999999')->get();

// NULL checks
$users = User::whereCryptedNull('phone')->get();
$users = User::whereCryptedNotNull('address')->get();

// LIKE search
$users = User::whereCryptedLike('address', '%Taipei%')->get();

// Combined queries
$users = User::where('name', 'John')
    ->whereCrypted('phone', '=', '0912345678')
    ->orWhereCryptedIn('address', ['Taipei', 'Kaohsiung'])
    ->get();

Batch Updates

$user = User::find(1);

// Batch update (including encrypted fields)
$user->updateEncrypted([
    'name' => 'Jane Doe',
    'phone' => '0987654321', // Will be encrypted
    'address' => 'Kaohsiung, Taiwan' // Will be encrypted
]);

Manual Encryption/Decryption

$user = new User();

// Manual encryption
$encryptedPhone = $user->encryptValue('phone', '0912345678');

// Manual decryption
$decryptedPhone = $user->decryptValue('phone', $encryptedPhone);

API Reference

Scope Methods

  • scopeWhereCrypted(Builder $query, string $column, string $operator, $value): Builder
  • scopeOrWhereCrypted(Builder $query, string $column, string $operator, $value): Builder
  • scopeWhereCryptedIn(Builder $query, string $column, array $values): Builder
  • scopeWhereCryptedNotIn(Builder $query, string $column, array $values): Builder
  • scopeWhereCryptedNot(Builder $query, string $column, string $operator, $value): Builder
  • scopeWhereCryptedBetween(Builder $query, string $column, $min, $max): Builder
  • scopeWhereCryptedNull(Builder $query, string $column): Builder
  • scopeWhereCryptedNotNull(Builder $query, string $column): Builder
  • scopeWhereCryptedLike(Builder $query, string $column, string $pattern): Builder

Instance Methods

  • encryptValue(string $column, $value): string
  • decryptValue(string $column, string $encryptedValue): ?string
  • updateEncrypted(array $data): bool
  • getEncryptedFields(): array
  • setEncryptedFields(array $fields): void
  • setEncryptionAlgorithm(string $algorithm): void
  • setEncryptionMode(string $mode): void
  • setEncryptionPadding(string $padding): void

Important Notes

  1. Performance: Encrypted queries are slower than regular queries due to database-level decryption
  2. Indexing: Encrypted fields cannot use regular indexes; consider separate search index tables if needed
  3. LIKE Searches: Due to encryption characteristics, LIKE searches have poor performance; use cautiously
  4. Key Management: Properly secure your encryption keys; lost keys mean unrecoverable data
  5. Backups: Include encryption keys when backing up data

Security Recommendations

  1. Use sufficiently strong encryption keys (recommend at least 32 characters)
  2. Regularly rotate encryption keys (requires re-encrypting existing data)
  3. Use different encryption keys in different environments
  4. Limit access to encryption keys
  5. Consider using Laravel's encryption service to protect the keys themselves

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.

统计信息

  • 总下载量: 1
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-08-14