Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Doctrine Encrypt Laravel Package

drjele/doctrine-encrypt

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require drjele/doctrine-encrypt
    

    Add to config/app.php under providers:

    Drjele\DoctrineEncrypt\DoctrineEncryptServiceProvider::class,
    
  2. Publish Config

    php artisan vendor:publish --provider="Drjele\DoctrineEncrypt\DoctrineEncryptServiceProvider"
    

    Configure encryption keys in .env:

    DOCTRINE_ENCRYPT_KEY=your-32-byte-key-here
    DOCTRINE_ENCRYPT_CIPHER=AES-256-CBC
    
  3. First Use Case Encrypt a field in an Eloquent model:

    use Drjele\DoctrineEncrypt\Type\EncryptedType;
    
    class User extends Model {
        protected $casts = [
            'credit_card' => EncryptedType::class,
        ];
    }
    

    Now User::create(['credit_card' => '4111111111111111']) will store an encrypted value.


Implementation Patterns

Common Workflows

  1. Field-Level Encryption Use EncryptedType in $casts for automatic encryption/decryption:

    protected $casts = [
        'ssn' => EncryptedType::class,
        'medical_history' => EncryptedType::class,
    ];
    
  2. Query Filtering Encrypted fields can be queried with raw SQL (avoid where clauses on encrypted fields):

    // ❌ Avoid
    User::where('credit_card', 'like', '4111%')->get();
    
    // ✅ Use raw SQL for exact matches
    User::whereRaw("credit_card = ENCRYPT('4111111111111111', ?)", [config('doctrine-encrypt.key')])->get();
    
  3. Bulk Operations Use update/create with encrypted arrays:

    User::create([
        'name' => 'John Doe',
        'encrypted_data' => ['key1' => 'value1', 'key2' => 'value2'], // Auto-encrypted if casted
    ]);
    
  4. Custom Encryption Logic Extend EncryptedType for per-field rules:

    class CustomEncryptedType extends EncryptedType {
        public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) {
            $fieldDeclaration['comment'] = 'Custom encrypted field';
            return parent::getSQLDeclaration($fieldDeclaration, $platform);
        }
    }
    
  5. API Responses Use toArray() or toJson()—decryption happens automatically:

    return User::find(1)->toArray(); // 'credit_card' is decrypted
    

Gotchas and Tips

Pitfalls

  1. Key Management

    • Never commit .env keys to version control.
    • Rotate keys periodically (requires re-encrypting all data).
    • Use Laravel’s config('doctrine-encrypt.key') for dynamic keys (e.g., from AWS KMS).
  2. Performance Overhead

    • Encryption adds ~10-20ms per field on write/read.
    • Avoid encrypting frequently queried fields (e.g., email for login).
  3. Database Compatibility

    • MySQL/MariaDB: Uses AES_ENCRYPT/AES_DECRYPT (requires AES plugin).
    • PostgreSQL: Uses pgp_sym_encrypt/pgp_sym_decrypt (install pgcrypto extension).
    • SQLite: Not supported (use Laravel’s native encryption for SQLite).
  4. Serialization Issues

    • Encrypted fields cannot be serialized/hashed (e.g., remember_token).
    • Avoid using encrypted fields in unique constraints or whereRaw with dynamic values.
  5. Migration Pitfalls

    • Never encrypt existing data in migrations—use a seeder or job:
      User::all()->each(fn ($user) => $user->forceFill(['ssn' => $user->ssn])->save());
      

Debugging Tips

  1. Verify Encryption Check raw DB values with:

    \DB::select("SELECT credit_card FROM users WHERE id = ?", [1]);
    

    Should return gibberish (e.g., ��⸮�⸮�⸮�⸮).

  2. Key Validation If decryption fails, test the key:

    $encrypted = \Drjele\DoctrineEncrypt\Encryptor::encrypt('test', config('doctrine-encrypt.key'));
    \Drjele\DoctrineEncrypt\Encryptor::decrypt($encrypted, config('doctrine-encrypt.key')); // Should return 'test'
    
  3. Logging Enable debug mode in config/doctrine-encrypt.php:

    'debug' => env('DOCTRINE_ENCRYPT_DEBUG', false),
    

    Logs encryption/decryption events to storage/logs/laravel.log.

Extension Points

  1. Custom Ciphers Implement Drjele\DoctrineEncrypt\EncryptorInterface:

    class ChaCha20Encryptor implements EncryptorInterface {
        public function encrypt($data, $key) { /* ... */ }
        public function decrypt($data, $key) { /* ... */ }
    }
    

    Bind it in AppServiceProvider:

    $this->app->bind(EncryptorInterface::class, ChaCha20Encryptor::class);
    
  2. Field-Specific Config Override defaults per field:

    protected $casts = [
        'ssn' => [
            'type' => EncryptedType::class,
            'cipher' => 'AES-128-CBC',
            'key' => 'custom-key-for-ssn',
        ],
    ];
    
  3. Event Listeners Hook into encryption events (e.g., log sensitive data access):

    \Drjele\DoctrineEncrypt\Events\Encrypting::class => [YourListener::class, 'handle'],
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen