caeligo/field-encryption-bundle
A Symfony bundle for transparent Doctrine entity field encryption using AES-256-CBC for string fields and AES-256-GCM for binary files.
#[Encrypted] and #[EncryptedFile] attributescomposer require caeligo/field-encryption-bundle
Register the bundle in config/bundles.php:
return [
// ...
Caeligo\FieldEncryptionBundle\FieldEncryptionBundle::class => ['all' => true],
];
php bin/console field-encryption:generate-key --append-to-env
# config/packages/field_encryption.yaml
field_encryption:
encryption_key: '%env(FIELD_ENCRYPTION_KEY)%'
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.
| 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 |
#[Encrypted(hashField: true)]
private ?string $email = null;
private ?string $plainEmail = null;
private ?string $emailHash = null;
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;
// From upload
$fileData = EncryptedFileData::fromUploadedFile($uploadedFile);
$entity->setPlainDocument($fileData);
// To download
$content = $entity->getPlainDocument()->getContent();
$mimeType = $entity->getPlainDocument()->getMimeType();
# 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
hashField for searchable fieldshash_pepper config for extra key separationThis 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.
MIT License - see LICENSE
BΓrΓ³ GΓ‘bor (@biga156)
How can I help you explore Laravel packages today?