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

Field Encryption Bundle Laravel Package

caeligo/field-encryption-bundle

View on GitHub
Deep Wiki
Context7

FieldEncryptionBundle

A Symfony bundle for transparent Doctrine entity field encryption using AES-256-CBC for string fields and AES-256-GCM for binary files.

PHP Symfony License

Features

  • πŸ” Automatic encryption/decryption - Transparent for your application code
  • πŸ“ String field encryption - AES-256-CBC with HMAC-SHA256 hash for searching
  • πŸ“ Binary file encryption - AES-256-GCM for documents, images, etc.
  • πŸ”‘ HKDF key derivation - Cryptographic key separation for different purposes
  • πŸ›‘οΈ Timing-safe comparison - Protection against timing attacks on hash verification
  • 🏷️ Attribute-based configuration - Simple #[Encrypted] and #[EncryptedFile] attributes
  • πŸ”„ Key rotation support - Safely rotate keys with progress tracking
  • πŸ—œοΈ Optional compression - Gzip compression for binary files
  • πŸ“‹ Metadata storage - Store MIME type, filename, size alongside encrypted content
  • πŸ› οΈ Console commands - Key generation, rotation wizard, data migration

Requirements

  • PHP 8.2+
  • Symfony 6.4+ or 7.x
  • Doctrine ORM 2.14+ or 3.x

Installation

composer require caeligo/field-encryption-bundle

Register the bundle in config/bundles.php:

return [
    // ...
    Caeligo\FieldEncryptionBundle\FieldEncryptionBundle::class => ['all' => true],
];

Quick Start

1. Generate Encryption Key

php bin/console field-encryption:generate-key --append-to-env

2. Configure the Bundle

# config/packages/field_encryption.yaml
field_encryption:
    encryption_key: '%env(FIELD_ENCRYPTION_KEY)%'

3. Add Attributes to Your Entity

use Caeligo\FieldEncryptionBundle\Attribute\Encrypted;
use Caeligo\FieldEncryptionBundle\Attribute\EncryptedEntity;

#[ORM\Entity]
#[EncryptedEntity]
class User
{
    #[ORM\Column(type: Types::TEXT, nullable: true)]
    #[Encrypted(hashField: true, hashProperty: 'emailHash')]
    private ?string $email = null;

    #[ORM\Column(type: Types::TEXT, nullable: true, unique: true)]
    private ?string $emailHash = null;

    private ?string $plainEmail = null;  // Transient, auto-populated

    public function getEmail(): ?string
    {
        return $this->plainEmail;
    }

    public function setEmail(?string $email): self
    {
        $this->plainEmail = $email;
        return $this;
    }
}

That's it! The bundle automatically encrypts on save and decrypts on load.

Documentation

Document Description
String Encryption Encrypting text fields (emails, names, etc.)
File Encryption Encrypting binary files (documents, images)
Console Commands Key generation, rotation, migration commands
Key Rotation Safely rotating encryption keys
Configuration Complete configuration reference

Basic Examples

Encrypted String Field

#[Encrypted(hashField: true)]
private ?string $email = null;

private ?string $plainEmail = null;
private ?string $emailHash = null;

Encrypted File Field

use Caeligo\FieldEncryptionBundle\Attribute\EncryptedFile;
use Caeligo\FieldEncryptionBundle\Model\EncryptedFileData;

#[EncryptedFile(mimeTypeProperty: 'mimeType', originalNameProperty: 'fileName')]
private $document;

private ?EncryptedFileData $plainDocument = null;
private ?string $mimeType = null;
private ?string $fileName = null;

Working with Files

// From upload
$fileData = EncryptedFileData::fromUploadedFile($uploadedFile);
$entity->setPlainDocument($fileData);

// To download
$content = $entity->getPlainDocument()->getContent();
$mimeType = $entity->getPlainDocument()->getMimeType();

Console Commands

# Generate new encryption key
php bin/console field-encryption:generate-key

# Rotate encryption keys (interactive wizard)
php bin/console field-encryption:rotate-keys --wizard

# Encrypt existing unencrypted data
php bin/console field-encryption:encrypt-existing --dry-run

Security Considerations

  • ⚠️ Never commit encryption keys - Use environment variables
  • πŸ’Ύ Backup your keys - Key loss = data loss
  • πŸ”„ Plan key rotation - Use the wizard for safe rotation
  • πŸ” Use hashes for search - Enable hashField for searchable fields
  • πŸ†” Use ULID/UUID - Don't use sequential integers for key derivation
  • 🌢️ Consider hash pepper - Use hash_pepper config for extra key separation

Database Compromise Protection

This bundle provides strong protection if only your database is compromised:

Attacker sees Can read? Notes
Encrypted fields ❌ No AES-256 encrypted
Hash fields ⚠️ Hash only HMAC-SHA256, not reversible
Plain metadata βœ… Yes Store sensitive metadata separately

Key requirement: The encryption key must NOT be stored in the database.

License

MIT License - see LICENSE

Author

BΓ­rΓ³ GΓ‘bor (@biga156)

Repository

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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle