# Laravel Db Encrypter Package Laravel Db Encrypter is a package designed to automatically encrypt and decrypt Eloquent model attribute values when storing and retrieving data from the database. It leverages Laravel's built-in `Crypt` facade to provide seamless encryption without requiring manual intervention on each database operation. The package integrates through a simple trait that can be added to any Eloquent model. Once configured with an array of encryptable attributes, the package automatically handles encryption on save and decryption on retrieval, making it transparent to the rest of your application code. It supports Laravel's native casting system, allowing you to work with typed values while maintaining encryption at the database layer. ## EncryptableDbAttribute Trait The core functionality is provided through the `EncryptableDbAttribute` trait, which overrides Eloquent's attribute handling methods to intercept values during read/write operations. When an attribute listed in the `$encryptable` array is saved, it is automatically encrypted using Laravel's `Crypt::encrypt()`. When retrieved, it is decrypted using `Crypt::decrypt()`. The trait preserves compatibility with Laravel's mutators, accessors, and casting system. ```php 'date', 'is_active' => 'boolean', ]; protected $fillable = [ 'name', 'id_number', 'email', 'phone', 'social_security_number', ]; } // Creating a new client - attributes are automatically encrypted before storage $client = Client::create([ 'name' => 'John Doe', 'id_number' => '123-45-6789', 'email' => 'john.doe@example.com', 'phone' => '+1-555-123-4567', 'social_security_number' => '987-65-4321', ]); // Retrieving client - attributes are automatically decrypted $client = Client::find(1); echo $client->email; // Output: john.doe@example.com (decrypted) echo $client->id_number; // Output: 123-45-6789 (decrypted) // Updating encrypted attributes $client->email = 'new.email@example.com'; $client->save(); // Email is automatically encrypted before storage // Converting to array - all encryptable attributes are decrypted $clientArray = $client->toArray(); // [ // 'id' => 1, // 'name' => 'John Doe', // 'id_number' => '123-45-6789', // 'email' => 'new.email@example.com', // 'phone' => '+1-555-123-4567', // 'social_security_number' => '987-65-4321', // ] // JSON serialization also returns decrypted values $clientJson = $client->toJson(); // {"id":1,"name":"John Doe","id_number":"123-45-6789","email":"new.email@example.com",...} ``` ## Database Migration for Encrypted Fields When using encryption, field values become longer due to the encrypted payload structure. The recommendation is to use `TEXT` type columns for encrypted fields to ensure the encrypted values fit properly. Below is an example migration setup. ```php id(); $table->string('name'); // Use TEXT for encrypted fields - encrypted values are larger $table->text('id_number'); $table->text('email'); $table->text('phone')->nullable(); $table->text('social_security_number')->nullable(); $table->timestamps(); }); } public function down(): void { Schema::dropIfExists('clients'); } }; // For existing tables, alter columns to TEXT return new class extends Migration { public function up(): void { Schema::table('clients', function (Blueprint $table) { $table->text('email')->change(); $table->text('phone')->change(); }); } }; ``` ## Working with Existing Unencrypted Data The package gracefully handles scenarios where you add encryption to existing data. Unencrypted values are returned as-is during read operations, and will be encrypted when saved. This allows for gradual migration of existing data. ```php credit_card_number; // Output: 4111-1111-1111-1111 (returned as-is) // After saving, the value becomes encrypted $user->credit_card_number = '4111-1111-1111-1111'; $user->save(); // Now stored encrypted in database // Batch encrypt existing records User::chunk(100, function ($users) { foreach ($users as $user) { // Simply saving triggers encryption of encryptable attributes $user->save(); } }); ``` ## Using with Laravel Casts The trait is designed to work seamlessly with Laravel's casting system. Decryption occurs before casting is applied, allowing you to cast encrypted JSON, arrays, or other types. ```php 'array', 'api_credentials' => 'object', ]; protected $fillable = [ 'user_id', 'settings', 'api_credentials', ]; } // Store encrypted JSON data $prefs = UserPreferences::create([ 'user_id' => 1, 'settings' => [ 'theme' => 'dark', 'notifications' => true, 'language' => 'en', ], 'api_credentials' => [ 'key' => 'sk_live_abc123', 'secret' => 'whsec_xyz789', ], ]); // Retrieve and work with cast types $prefs = UserPreferences::where('user_id', 1)->first(); echo $prefs->settings['theme']; // Output: dark echo $prefs->api_credentials->key; // Output: sk_live_abc123 // Update nested values $prefs->settings = array_merge($prefs->settings, ['theme' => 'light']); $prefs->save(); // Array is JSON-encoded, then encrypted before storage ``` ## Summary Laravel Db Encrypter is ideal for applications that need to store sensitive personal information (PII), financial data, or any confidential information in the database. Common use cases include encrypting social security numbers, credit card details, medical records, API keys, and personal contact information. The package requires no changes to your application logic since encryption and decryption happen transparently at the model layer. Integration follows a straightforward pattern: add the trait to your model, define the `$encryptable` array with attribute names, and ensure your database columns can accommodate the larger encrypted values (preferably TEXT type). The package works with Laravel's existing features including accessors, mutators, casting, and serialization. For production use, ensure your `APP_KEY` environment variable is properly set, as it's used by Laravel's Crypt facade for all encryption operations.