You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Updated CONFIGURATION.md to clarify the use of the `<ENC>` marker in MySQL and its implications for data insertion and retrieval.
- Expanded MYSQL_AES.md with detailed examples for inserting encrypted data using both Doctrine and native SQL, emphasizing the importance of column types and formats to avoid confusion.
Copy file name to clipboardExpand all lines: docs/CONFIGURATION.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -69,7 +69,7 @@ Each config has its own key file: `.{encryptor_class}.{alias}.key` (e.g. `.Halit
69
69
```
70
70
71
71
- **MysqlAes**
72
-
Compatible with MySQL [`AES_ENCRYPT()`](https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html) / [`AES_DECRYPT()`](https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html) (AES-128-ECB, default `block_encryption_mode`). The passphrase is a plain string (file or env). Use a **BLOB** column when encrypting in SQL. See [MYSQL_AES.md](MYSQL_AES.md) and the symfony8 demo (`/mysql-aes-note`). **Performance:** PHP OpenSSL on every ORM read/write; SQL `AES_ENCRYPT` only avoids PHP on insert/update for columns you manage in raw SQL. Searching secrets via `LIKE` on decrypted values in SQL is among the most expensive patterns — see [PERFORMANCE.md](PERFORMANCE.md).
72
+
Compatible with MySQL [`AES_ENCRYPT()`](https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html) / [`AES_DECRYPT()`](https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html) (AES-128-ECB, default `block_encryption_mode`). The passphrase is a plain string (file or env). Use a **BLOB** column when encrypting in SQL. See [MYSQL_AES.md](MYSQL_AES.md) (INSERT examples, repository pattern, demo `/mysql-aes-note`) and the symfony8 demo routes under `/mysql-aes-note`. **Performance:** PHP OpenSSL on every ORM read/write; SQL `AES_ENCRYPT` only avoids PHP on insert/update for columns you manage in raw SQL. Searching secrets via `LIKE` on decrypted values in SQL is among the most expensive patterns — see [PERFORMANCE.md](PERFORMANCE.md).
### Advanced: SQL `INSERT` into an ORM column **with**`<ENC>` (MySQL only)
105
+
106
+
Only if you **must** insert in SQL but read via Doctrine/`#[Encrypted('mysql_aes')]` on the **same** column. The ciphertext bytes from MySQL must match PHP `MysqlAes` (same passphrase, default `block_encryption_mode`).
Prefer **VARBINARY/BLOB** for binary-safe storage; the demo uses `TEXT` for `secret_orm` (works for typical UTF-8 secrets but binary in `TEXT` can be charset-sensitive).
117
+
118
+
After insert, `$em->find(MysqlAesNote::class, $id)` should decrypt on load.
119
+
**Do not** use this on `secret_native` if you also use `AES_DECRYPT` there — choose one format per column.
120
+
121
+
## Inserting encrypted data in MySQL (native SQL)
122
+
123
+
Use this when the **ciphertext must be produced by MySQL** (`AES_ENCRYPT`), e.g. legacy data, ETL, or another service writing directly to the DB. The plaintext is **not** stored; only the binary result of `AES_ENCRYPT` goes into the column.
124
+
125
+
### 1. Table and column type
126
+
127
+
Store ciphertext in **BLOB** or **VARBINARY** (not plain `TEXT`/`VARCHAR`):
128
+
129
+
```sql
130
+
CREATETABLEmy_secrets (
131
+
id INT AUTO_INCREMENT PRIMARY KEY,
132
+
title VARCHAR(255) NOT NULL,
133
+
secret_native BLOB NULL
134
+
);
135
+
```
136
+
137
+
The **passphrase** is the same string you configure for `MysqlAes` (`MYSQL_AES_KEY` or key file content). MySQL pads it to 16 bytes internally (AES-128-ECB, default `block_encryption_mode`).
138
+
139
+
### 2. INSERT in SQL (mysql client)
140
+
141
+
Replace the passphrase with your env value (never commit real keys):
| **Native MySQL** | `INSERT … AES_ENCRYPT(:plain, :key)` | `secret_native` BLOB | Raw MySQL AES blob, **no** `<ENC>` |
243
+
| **SQL for ORM (advanced)** | `INSERT … CONCAT(AES_ENCRYPT(…), '<ENC>')` | `secret_orm` | MySQL AES blob + `<ENC>` (see section above) |
244
+
245
+
`AES_DECRYPT`on a Doctrine `secret_orm` value will **not** return the original text.
246
+
`{{ x|decrypt('mysql_aes') }}`does **nothing** unless `x` ends with `<ENC>`.
247
+
248
+
### 7. Same key as the bundle `MysqlAes` encryptor
249
+
250
+
The passphrase in SQL must match the config used by PHP:
251
+
252
+
```yaml
253
+
nowo_doctrine_encrypt:
254
+
configs:
255
+
mysql_aes:
256
+
encryptor_class: MysqlAes
257
+
secret_key_env_var: '%env(MYSQL_AES_KEY)%'
258
+
```
259
+
260
+
Then rows inserted with `AES_ENCRYPT(..., :key)` and rows encrypted via `#[Encrypted('mysql_aes')]` use the **same algorithm**, but **different storage formats** unless you only use the native BLOB column for SQL inserts.
261
+
262
+
## Native SQL (repository / read)
34
263
35
264
For **pure** `AES_ENCRYPT` / `AES_DECRYPT` in SQL (no `<ENC>` marker), use a **BLOB** (or VARBINARY) column and bind the **passphrase** (not the derived key bytes):
0 commit comments