Weave Code
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

Laravel Database Encryption Laravel Package

austinheap/laravel-database-encryption

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require austinheap/laravel-database-encryption
    

    Publish the config file:

    php artisan vendor:publish --provider="AustinHeap\DatabaseEncryption\DatabaseEncryptionServiceProvider"
    
  2. Configure Encryption Keys: Edit config/database-encryption.php and set:

    'key' => env('ENCRYPTION_KEY', 'your-32-character-key-here'),
    'cipher' => 'AES-256-CBC', // Default, but can be adjusted
    
  3. First Use Case: Define encrypted attributes in your Eloquent model:

    use AustinHeap\DatabaseEncryption\Traits\Encryptable;
    
    class User extends Model
    {
        use Encryptable;
    
        protected $encryptable = ['ssn', 'credit_card'];
    }
    

    Now, ssn and credit_card will be automatically encrypted/decrypted.


Implementation Patterns

Core Workflows

  1. Model-Level Encryption:

    • Use the Encryptable trait in Eloquent models.
    • Define $encryptable array to specify fields to encrypt.
    • Example:
      class Patient extends Model
      {
          use Encryptable;
      
          protected $encryptable = ['medical_history', 'insurance_number'];
      }
      
  2. Dynamic Encryption:

    • Encrypt fields dynamically via encrypt() and decrypt() methods:
      $user = new User();
      $user->ssn = $user->encrypt('123-45-6789'); // Manually encrypt
      $user->save();
      
  3. Querying Encrypted Fields:

    • Use whereEncrypted() for querying encrypted fields:
      $users = User::whereEncrypted('ssn', '123-45-6789')->get();
      
  4. Mass Assignment:

    • Ensure encrypted fields are included in $fillable:
      protected $fillable = ['name', 'ssn', 'credit_card'];
      

Integration Tips

  1. Migrations:

    • No need to modify migrations; the package handles encryption/decryption transparently.
  2. API Responses:

    • Encrypted fields will be decrypted in API responses automatically (if using Laravel's default JSON responses).
  3. Testing:

    • Mock the encryption service in tests:
      $this->app->instance('encrypter', Mockery::mock('overload:\Illuminate\Contracts\Encryption\Encrypter'));
      
  4. Seeding:

    • Use encrypt() in seeders to store encrypted data:
      User::create([
          'name' => 'John Doe',
          'ssn' => (new User)->encrypt('123-45-6789'),
      ]);
      

Gotchas and Tips

Pitfalls

  1. Key Management:

    • The encryption key must be 32 characters long for AES-256-CBC. Use openssl_random_pseudo_bytes(32) to generate a secure key.
    • Store the key in .env (e.g., ENCRYPTION_KEY=your-key-here) and never commit it to version control.
  2. Performance Overhead:

    • Encryption/decryption adds CPU overhead. Avoid encrypting large text fields (e.g., description).
    • Benchmark performance if encrypting frequently accessed fields.
  3. Query Limitations:

    • Encrypted fields cannot be used in orderBy, groupBy, or raw SQL queries directly. Use whereEncrypted() instead.
    • Example of incorrect usage:
      // ❌ Won't work
      User::orderBy('ssn')->get();
      
    • Example of correct usage:
      // ✅ Works
      User::whereEncrypted('ssn', '123-45-6789')->get();
      
  4. Serialization Issues:

    • Encrypted fields may cause issues with Laravel's serialization (e.g., session() or cache()). Exclude them from $guarded or use serialize/unserialize carefully.
  5. Database Indexes:

    • Encrypted fields cannot be indexed in the database (since their values are hashed). Avoid adding indexes to encrypted columns.

Debugging Tips

  1. Verify Encryption:

    • Check if a field is encrypted by inspecting the database value (should be gibberish) and the model attribute (should be readable):
      $user = User::find(1);
      dd($user->ssn); // Should be decrypted
      dd($user->getAttribute('ssn')); // Same as above
      
  2. Log Encryption Errors:

    • Enable Laravel's debug mode (APP_DEBUG=true) to catch encryption-related exceptions.
  3. Check Cipher Configuration:

    • If decryption fails, verify the cipher setting in config/database-encryption.php matches the key length (e.g., AES-256-CBC for 32-byte keys).
  4. Clear Cache:

    • After updating the config or models, run:
      php artisan cache:clear
      php artisan config:clear
      

Extension Points

  1. Custom Encryption Logic:

    • Override the encrypt() and decrypt() methods in your model:
      public function encrypt($value)
      {
          return parent::encrypt($value . '-custom-suffix');
      }
      
  2. Conditional Encryption:

    • Dynamically set $encryptable based on conditions (e.g., user role):
      protected $encryptable = [];
      
      public function setEncryptableAttribute()
      {
          if ($this->isAdmin()) {
              $this->encryptable = ['api_key'];
          }
      }
      
  3. Global Encryption Rules:

    • Use model events to modify encryption behavior:
      class User extends Model
      {
          protected static function boot()
          {
              parent::boot();
      
              static::retrieved(function ($user) {
                  if (!$user->isTrusted()) {
                      $user->encryptable = ['email']; // Encrypt email for untrusted users
                  }
              });
          }
      }
      
  4. Fallback for Missing Key:

    • Handle missing encryption keys gracefully:
      try {
          $value = $this->decrypt($encryptedValue);
      } catch (\Exception $e) {
          Log::warning('Encryption key missing for field: ' . $this->getKey());
          return $encryptedValue; // Fallback to raw value
      }
      
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity