Pour crypter une base de données, il existe au moins 3 façons de faire :
- Encryptage du disque
- Encryptage de la base de données
- Encryptage au niveau de l’application avant insertion dans la base de données
Dans l’exemple qui va suivre nous allons utiliser la deuxième solution avec une des bases de données suivantes :
- MariaDB 10.1.3+
- Mysql / Percona Server 5.7.11+
Mysql et Percona Server ne permettent que l’encryptage des tables innodb tandis que MariaDB permet d’encrypter les undo/redo logs ainsi que les logs binaires en plus.
L’implementation sera donc différente selon le serveur de base de données qui sera utilisé.
Nous allons décrire ici l’implémentation pour MariaDB.
Création du fichier contenant la clef d’encryptage.
1 2 3 4 5 6 | openssl enc -aes-256-cbc -P -md sha1 enter aes-256-cbc encryption password: Verifying - enter aes-256-cbc encryption password: salt=C86B3CDB07C10213 key=29EE4F5E80B9597A98819C46117D70EC7A2EA7A9E096A89F297A62005ACB112B iv =80FFE0A5D8B2BF8DAE9EC200C0F7FDE4 |
On stocke le résultat dans un fichier qu’on appelera keys.txt en utilisant le format suivant : 1;iv;key
1 2 | cat keys.txt 1;80FFE0A5D8B2BF8DAE9EC200C0F7FDE4;29EE4F5E80B9597A98819C46117D70EC7A2EA7A9E096A89F297A62005ACB112B |
Configuration dans my.cnf
1 2 3 4 5 6 7 8 9 | [mysqld] plugin- load - add =file_key_management.so file_key_management_filekey = /etc/mysql/keys.txt innodb-encrypt-tables = FORCE innodb-encrypt-log innodb-encryption-threads=1 encrypt-tmp-disk-tables=1 encrypt-tmp-files=1 encrypt-binlog=1 |
En utilisant la valeur FORCE pour la variable innodb-encrypt-tables, on force l’encryption pour toutes les tables
même si les développeurs mettent « encrypted=no » lors de la création d’une table.
Si on désire avoir des tables cryptées et d’autres non, on mettra cette variable à ON pour laisser le choix aux
développeurs. Il sera alors impératif d’avoir la variable suivante active :
innodb_file_per_file
Vérification du fonctionnement
On redémarre d’abord notre base de données afin d’appliquer la nouvelle configuration.
On vérifie ensuite que le plugins est bien chargé:
1 2 3 4 | show plugins; ... | file_key_management | ACTIVE | ENCRYPTION | file_key_management.so | GPL | ... |
On insère notre base et on vérifie que les tables sont bien encryptées via la commande suivante:
1 2 3 4 5 6 7 8 9 | select name from information_schema.INNODB_TABLESPACES_ENCRYPTION where ENCRYPTION_SCHEME=1; + -------------------+ | name | + -------------------+ | test/mtt_user | | test/mtt_country | | test/mtt_phone | | test/mtt_email | + -------------------+ |
Limitation
Mysqlbinlog ne fonctionne pas avec les binlogs cryptés.
Percona XtraBackup ne fonctionne pas.
Les dump mysql ne sont pas cryptés.
Il existe encore des expositions possibles des données :
- Les logs relay sur les slaves non cryptés
- Le log des slow query
- Le log d’erreur
- Le log général
- Le log d’audit
Désactivation de l’encryptage
- Si la variable innodb-encrypt-tables est sur FORCE, on la modifie sur ON (relance de MariaDB obligatoire)
- On modifie toutes les tables avec encryption=no
- On supprime toute la configuration dans my.cnf et on relance MariaDB.