Heu, il faut chiffrer les données de la base ! On fait comment ?
C'est une bonne question !
Je vous présente un cas réel et une solution avec PostgreSQL.
Après un résumé des différentes technique de chiffrement, je présente une méthode permettant de répondre à ce problème sur une application existante.
Vidéo de la présentation au PGDay 2021 : https://youtu.be/LWVaMEC8j1k
12. CHIFFREMENT DES DISQUES
Simple de mise en œuvre
Protège contre les vols physiques
Conservation des fonctionnalités
de la BDD
Backup non chiffré
Si compromission de la machine,
les données sont en clair
À faire lors de l'installation de la
machine
13. CHIFFREMENT DE L'INSTANCE DE LA
BASE DE DONNÉES
Transparent Data Encryption
Protège contre l'exfiltration des
fichiers
Conservation des fonctionnalités
de la BDD
Backup fichier chiffré
Backup non chiffré via pg_dump
Si compromission de la BDD, les
données sont en clair
Nécessite une installation
14. CHIFFREMENT DES COLONNES DE LA
BASE DE DONNÉES
Aucune installation
supplémentaire
Backup chiffré
Perte de fonctionnalité de la BDD
(recherche, unicité, index, ...)
15. CHIFFREMENT DE LA DONNÉE PAR
L'APPLICATION
La BDD reçoit des données
chiffrées
Backup chiffré
Perte de fonctionnalité de la BDD
(recherche, unicité, index, ...)
16. CHIFFREMENT DE LA DONNÉE PAR LE
NAVIGATEUR
L'application et la BDD reçoivent
des données chiffrées
Backup chiffré
Perte de fonctionnalité de la BDD
(recherche, unicité, index, ...)
Pas de contrôle de données
Mauvaises expériences
20. ET MAINTENANT ?
Chiffrement dans la base de données
Création de vue des données déchiffrées
Création des tables chiffrées
Ajout de trigger de mise à jour sur la vue
21. CRÉATION DES TABLES CHIFFRÉES
CREATE TABLE private.candidate_form (
id integer NOT NULL GENERATED BY DEFAULT AS IDENTITY
PRIMARY KEY,
first_name bytea,
last_name bytea,
pee_identifier bytea,
email bytea,
-- ...
);
22. CRÉATION DES VUES DÉCHIFFRÉES
Comment passer la clé secrète à la vue ?
23. LA CLÉ
SET application.key='mySecret';
-- ...
SELECT current_setting('application.key');
1
2
3
SET application.key='mySecret';
1
-- ...
2
SELECT current_setting('application.key');
3 SELECT current_setting('application.key');
SET application.key='mySecret';
1
-- ...
2
3
24. CRÉATION DES VUES DÉCHIFFRÉES
CREATE VIEW candidate_form AS
SELECT id,
pgp_sym_decrypt(
first_name,
current_setting('application.key')
) AS first_name,
-- ...
FROM private.candidate_form;
1
2
3
4
5
6
7
8
pgp_sym_decrypt(
first_name,
current_setting('application.key')
) AS first_name,
CREATE VIEW candidate_form AS
1
SELECT id,
2
3
4
5
6
-- ...
7
FROM private.candidate_form;
8
25. TRIGGER DE VUE : INSERT
CREATE FUNCTION encryption_insert() RETURNS trigger AS $$
BEGIN
INSERT INTO private.candidate_form (
first_name, -- ...
) VALUES (
pgp_sym_encrypt(
NEW.first_name,
current_setting('application.key')
), -- ...
);
return NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
1
2
3
4
5
6
7
8
9
10
11
12
13
INSERT INTO private.candidate_form (
first_name, -- ...
) VALUES (
pgp_sym_encrypt(
NEW.first_name,
current_setting('application.key')
), -- ...
);
return NEW;
CREATE FUNCTION encryption_insert() RETURNS trigger AS $$
1
BEGIN
2
3
4
5
6
7
8
9
10
11
END;
12
$$ LANGUAGE plpgsql SECURITY DEFINER;
13
pgp_sym_encrypt(
NEW.first_name,
current_setting('application.key')
), -- ...
);
CREATE FUNCTION encryption_insert() RETURNS trigger AS $$
1
BEGIN
2
INSERT INTO private.candidate_form (
3
first_name, -- ...
4
) VALUES (
5
6
7
8
9
10
return NEW;
11
END;
12
$$ LANGUAGE plpgsql SECURITY DEFINER;
13
26. TRIGGER DE VUE : UPDATE
CREATE FUNCTION encryption_update() RETURNS trigger AS $$
BEGIN
UPDATE private.candidate_form SET
first_name = pgp_sym_encrypt(
NEW.first_name,
current_setting('application.key')
),
-- ...
WHERE id = OLD.id;
return NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
1
2
3
4
5
6
7
8
9
10
11
12
UPDATE private.candidate_form SET
first_name = pgp_sym_encrypt(
NEW.first_name,
current_setting('application.key')
),
-- ...
WHERE id = OLD.id;
return NEW;
CREATE FUNCTION encryption_update() RETURNS trigger AS $$
1
BEGIN
2
3
4
5
6
7
8
9
10
END;
11
$$ LANGUAGE plpgsql SECURITY DEFINER;
12
first_name = pgp_sym_encrypt(
NEW.first_name,
current_setting('application.key')
),
-- ...
CREATE FUNCTION encryption_update() RETURNS trigger AS $$
1
BEGIN
2
UPDATE private.candidate_form SET
3
4
5
6
7
8
WHERE id = OLD.id;
9
return NEW;
10
END;
11
$$ LANGUAGE plpgsql SECURITY DEFINER;
12