aeliot/doctrine-encrypted-types
Installation
composer require aeliot/doctrine-encrypted-types
Ensure doctrine/doctrine-bundle is also installed (required dependency).
First Use Case: Encrypting a Field
Entity:
use Aeliot\DoctrineEncryptedTypes\Types\EncryptedStringType;
/**
* @ORM\Column(type="encrypted_string")
*/
private $sensitiveData;
config/packages/doctrine_encrypted.yaml:
aeliot_doctrine_encrypted:
encryption_keys:
- '%env(ENCRYPTION_KEY)%'
Key Setup
Generate a secure key (e.g., 32-byte AES-256) and store it in .env:
ENCRYPTION_KEY=your_32_byte_base64_encoded_key_here
Entity Integration
encrypted_string, encrypted_text, encrypted_int, etc.) for sensitive fields.User entity:
/**
* @ORM\Column(type="encrypted_string")
*/
private $creditCardNumber;
public function getCreditCardNumber(): ?string
{
return $this->creditCardNumber;
}
Custom Encryption Logic
EncryptedType for custom behavior:
use Aeliot\DoctrineEncryptedTypes\Types\EncryptedType;
class CustomEncryptedType extends EncryptedType
{
public function getName(): string
{
return 'custom_encrypted_string';
}
}
services.yaml:
services:
App\Doctrine\CustomEncryptedType:
tags: [doctrine.type]
Querying Encrypted Data
EncryptedExpressionBuilder for comparisons:
$qb = $entityManager->createQueryBuilder();
$qb->andWhere(
$qb->expr()->eq(
'entity.sensitiveField',
$qb->expr()->literal('plaintext_value')
)
);
// Automatically decrypts during query execution.
Bulk Operations
DoctrineEncryptedBundle for batch encryption/decryption (if installed):
$em->getRepository(User::class)->encryptField('creditCardNumber', $users);
Key Management
Performance Overhead
// Disable encryption for non-sensitive fields to avoid unnecessary overhead.
/**
* @ORM\Column(type="string")
*/
private $nonSensitiveField;
Query Limitations
ORDER BY, GROUP BY, or complex aggregations (e.g., SUM). Decrypt first in application logic if needed.Doctrine Cache Invalidation
php bin/console doctrine:cache:clear-metadata
Enable Logging
Add to config/packages/monolog.yaml:
handlers:
doctrine_encrypted:
type: stream
path: "%kernel.logs_dir%/doctrine_encrypted.log"
level: debug
channels: ["doctrine"]
Verify Encryption Check raw database values vs. decrypted values:
$user = $em->find(User::class, 1);
var_dump($user->getCreditCardNumber()); // Decrypted
var_dump($em->getConnection()->fetchOne('SELECT credit_card_number FROM user WHERE id = 1')); // Encrypted
Common Errors
encryption_keys is configured in doctrine_encrypted.yaml.services.yaml with the doctrine.type tag.Custom Cipher
Override getCipher() in a custom type for non-AES encryption (e.g., ChaCha20):
protected function getCipher(): string
{
return 'chacha20';
}
Key Derivation
Use getKey() to implement key derivation (e.g., PBKDF2) from a master key:
protected function getKey(): string
{
return hash_hmac('sha256', $this->masterKey, 'salt');
}
Field-Level Configuration Use attributes for dynamic encryption (Laravel-style):
use Aeliot\DoctrineEncryptedTypes\Attributes\Encrypted;
#[Encrypted(key: 'special_key')]
private $apiToken;
(Note: Requires custom attribute listener.)
How can I help you explore Laravel packages today?