kyzegs/doctrine-encryption-bundle
Composer 安装命令:
composer require kyzegs/doctrine-encryption-bundle
包简介
Doctrine field encryption and blind indexes for Symfony applications.
README 文档
README
Doctrine Encryption Bundle
Field-level authenticated encryption and blind indexes for Doctrine entities in Symfony applications.
Maintained fork published as kyzegs/doctrine-encryption-bundle, replacing the unmaintained original package.
Requirements
- PHP 8.2 or newer
- Symfony 6.4, 7.4, or 8.x
- Doctrine ORM 2.20 or 3.x
- OpenSSL with AES-256-GCM support
Installation
composer require kyzegs/doctrine-encryption-bundle
Register the bundle if Symfony Flex has not already done so:
// config/bundles.php return [ Kyzegs\DoctrineEncryptionBundle\DoctrineEncryptionBundle::class => ['all' => true], ];
Generate a 256-bit key:
bin/console encrypt:genkey
Store the result in a secret manager or an uncommitted environment file:
DOCTRINE_ENCRYPTION_ENCRYPT_KEY=base64-encoded-key DOCTRINE_ENCRYPTION_BLIND_INDEX_KEY=a-different-secret
Configure the bundle:
# config/packages/doctrine_encryption.yaml doctrine_encryption: encrypt_key: '%env(DOCTRINE_ENCRYPTION_ENCRYPT_KEY)%' blind_index_key: '%env(DOCTRINE_ENCRYPTION_BLIND_INDEX_KEY)%' key_id: '2026-01'
The encryption and blind-index keys should be different. Never commit either key.
Encrypting fields
Use the PHP attribute on a Doctrine string field. Allow room for the versioned ciphertext envelope; TEXT is the least surprising choice.
use Doctrine\ORM\Mapping as ORM; use Kyzegs\DoctrineEncryptionBundle\Attribute\Encrypted; #[ORM\Column(type: 'text', nullable: true)] #[Encrypted] private ?string $personalNumber = null;
New values are written with AES-256-GCM in a versioned, authenticated envelope. The entity contains plaintext while it is in memory; Doctrine stores ciphertext. Existing unversioned AES-CBC and AES-GCM values from older bundle versions remain readable.
External XML, YAML, or PHP Doctrine mappings can opt in without modifying the entity:
<field name="personalNumber" type="text"> <options> <option name="encrypted">true</option> </options> </field>
The equivalent field option is encrypted: true.
Encrypted scalar properties inside Doctrine embeddables are supported. Mark the embeddable property normally; bundle uses Doctrine's nested field path for encryption, decryption, change tracking, and database maintenance:
#[ORM\Embeddable] final class ContactDetails { #[ORM\Column(type: 'text')] #[Encrypted] public string $privateNote; }
Searching encrypted values
Randomized encryption cannot be queried by plaintext and must not carry a meaningful unique constraint. Add a blind-index column instead:
use Kyzegs\DoctrineEncryptionBundle\Attribute\BlindIndex; use Kyzegs\DoctrineEncryptionBundle\Attribute\Encrypted; #[ORM\Column(type: 'text')] #[Encrypted] private string $email; #[ORM\Column(type: 'string', length: 64, unique: true, nullable: true)] #[BlindIndex(sourceField: 'email', normalizer: BlindIndex::NORMALIZE_LOWERCASE)] private ?string $emailLookupHash = null;
Create the same hash when querying:
use Kyzegs\DoctrineEncryptionBundle\Hashers\BlindIndexHasherInterface; $hash = $blindIndexHasher->hash($email, BlindIndex::NORMALIZE_LOWERCASE); $user = $repository->findOneBy(['emailLookupHash' => $hash]);
Available normalizers are none, trim, lowercase, and uppercase. Blind indexes reveal equality patterns; use them only for fields that genuinely need lookups.
Rebuild indexes in bounded batches:
bin/console encrypt:blind-index --batch-size=500 --dry-run bin/console encrypt:blind-index --batch-size=500
Key rotation
Change the current key and key ID, then retain old keys under decryption_keys:
doctrine_encryption: encrypt_key: '%env(DOCTRINE_ENCRYPTION_ENCRYPT_KEY_2026)%' key_id: '2026' decryption_keys: '2025': '%env(DOCTRINE_ENCRYPTION_ENCRYPT_KEY_2025)%'
Back up the database, inspect the operation, and rotate in batches:
bin/console encrypt:database rotate --dry-run bin/console encrypt:database rotate --batch-size=250
Remove a retired key only after every value using its key ID has been rotated and verified.
Database maintenance
The maintenance command supports encrypt, decrypt, and rotate, custom and composite scalar identifiers, quoted identifiers, transactions, batches, confirmation, and dry runs:
bin/console encrypt:database encrypt --dry-run bin/console encrypt:database decrypt --manager=tenant --batch-size=100
Association identifiers are rejected because they cannot be updated safely by the low-level command. Always take a verified backup before a write operation.
Multiple Doctrine connections
doctrine_encryption: encrypt_key: '%env(DOCTRINE_ENCRYPTION_ENCRYPT_KEY)%' connections: ['default', 'tenant']
Optional Twig filter
Install Twig and leave enable_twig enabled to expose value|decrypt:
composer require symfony/twig-bundle
Decrypting in templates increases the number of places where plaintext exists. Prefer decrypting only at the application boundary that needs it.
Custom integrations
KeyProviderInterface is the extension point for Vault, KMS, HSM, or another secret source. It returns binary 32-byte keys and supports lookup by ciphertext key ID. Register the implementation as a service and configure it directly:
doctrine_encryption: key_provider_service: 'App\\Encryption\\KmsKeyProvider' blind_index_key: '%env(DOCTRINE_ENCRYPTION_BLIND_INDEX_KEY)%'
Likewise, encryptor_service accepts any registered EncryptorInterface service with arbitrary injected dependencies. encryptor_class remains available as a deprecated compatibility path for classes using the historical event-dispatcher constructor.
Security notes
- Encryption does not replace access control, TLS, backups, audit logging, or database hardening.
- Losing an encryption key permanently loses the corresponding data.
- Application compromise can expose plaintext and keys while the process is running.
- Blind indexes permit equality analysis and should use a separate high-entropy secret.
- Test restoration and rotation on a copy of production data before operating on production.
See UPGRADE.md before upgrading an existing installation and SECURITY.md for vulnerability reporting.
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-22