Les infos stockées dans une base de données, c'est souvent super précieux pour une boîte. Mais, malheureusement, ça attire aussi les hackers. C'est pour ça qu'il faut penser au chiffrement — c'est un des moyens de protéger les données des curieux.
Le chiffrement aide à garder confidentielles des infos sensibles : genre les mots de passe, les numéros de cartes bancaires ou les données perso. Ça aide aussi à respecter des lois comme le GDPR ou le HIPAA. Et si jamais il y a une fuite, les données chiffrées seront beaucoup moins vulnérables, donc ça limite la casse.
Dans PostgreSQL, t'as des fonctions pratiques pour le chiffrement symétrique. Avec pgp_sym_encrypt(data, key) tu peux chiffrer les données que tu veux, puis les déchiffrer avec pgp_sym_decrypt(encrypted_data, key) en utilisant la même clé. C'est simple — et safe.
Exemple de chiffrement de données
Étape 1 : Création de la table
On va créer une table users avec une colonne qui va stocker les numéros de téléphone chiffrés :
-- Création d'une table avec une colonne pour stocker les données chiffrées
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username TEXT NOT NULL,
phone_encrypted BYTEA -- Ici on va stocker les numéros de téléphone chiffrés
);
Étape 2 : Ajout de données avec chiffrement
Maintenant on ajoute un utilisateur, en chiffrant son numéro de téléphone :
-- Insertion de données avec chiffrement
INSERT INTO users (username, phone_encrypted)
VALUES ('john_doe', pgp_sym_encrypt('123-456-7890', 'my_secret_key'));
Fais gaffe à l'utilisation de la fonction pgp_sym_encrypt. my_secret_key — c'est notre clé symétrique. Dans la vraie vie, la clé doit être bien complexe et super protégée.
Étape 3 : Extraction des données avec déchiffrement
Quand tu veux accéder aux données, tu peux les déchiffrer :
-- Extraction des données avec déchiffrement
SELECT
username,
pgp_sym_decrypt(phone_encrypted, 'my_secret_key') AS phone
FROM users;
Si la clé est bonne, tu verras le numéro de téléphone d'origine.
Aller plus loin : ajouter du chiffrement dans une table existante
Et si la table existe déjà et qu'on veut commencer à chiffrer une de ses colonnes ? On va voir comment faire.
Étape 1 : Création d'une nouvelle colonne
Imaginons qu'on a une table customers, et qu'on veut chiffrer les colonnes avec les numéros de carte bancaire :
-- Ajout d'une nouvelle colonne pour les données chiffrées
ALTER TABLE customers ADD COLUMN card_number_encrypted BYTEA;
Étape 2 : Migration des données dans la colonne chiffrée
On chiffre les données existantes et on les met dans la nouvelle colonne :
-- Chiffrement des données et migration dans la nouvelle colonne
UPDATE customers
SET card_number_encrypted = pgp_sym_encrypt(card_number, 'my_other_secret_key');
Étape 3 : Suppression de la colonne non chiffrée
Après avoir bien chiffré les données, on peut supprimer l'ancienne colonne :
-- Suppression de l'ancienne colonne non chiffrée
ALTER TABLE customers DROP COLUMN card_number;
Maintenant les données sont protégées par chiffrement, et tu peux y accéder seulement si t'as la clé.
Particularités du travail avec des données chiffrées
Y'a quelques points importants quand tu bosses avec des colonnes chiffrées :
Type de données :
- Les valeurs chiffrées sont stockées en format binaire (
BYTEA), pas en clair. - Pour les requêtes, il faut utiliser les fonctions de déchiffrement.
Recherche et filtrage :
- Tu peux pas chercher directement des lignes avec des données chiffrées, genre :
SELECT * FROM users WHERE phone_encrypted = '123-456-7890'; -- ÇA NE MARCHERA PAS !
- À la place, tu peux déchiffrer les données dans la requête :
SELECT *
FROM users
WHERE pgp_sym_decrypt(phone_encrypted, 'my_secret_key') = '123-456-7890';
Performance :
Le chiffrement et le déchiffrement peuvent ralentir les requêtes. Utilise-les seulement là où c'est vraiment nécessaire.
Cas concret : protection des mots de passe
Stocker les mots de passe — c'est un des cas les plus courants pour le chiffrement. Au lieu de garder les mots de passe en clair (mauvaise idée), il faut les hasher.
Hashage du mot de passe avec pgcrypto
On va utiliser la fonction crypt() pour hasher les mots de passe de façon sécurisée :
-- Hashage du mot de passe à l'insertion
INSERT INTO users (username, phone_encrypted)
VALUES ('alice', crypt('my_secure_password', gen_salt('bf')));
Ici gen_salt('bf') génère un salt pour le hash du mot de passe.
Pour vérifier un mot de passe, on compare son hash :
-- Comparaison du mot de passe hashé
SELECT username
FROM users
WHERE crypt('my_secure_password', phone_encrypted) = phone_encrypted;
Conseils de sécurité
- Stocke les clés à part :
Ne garde jamais les clés symétriques dans la même base que les données chiffrées.
- Utilise des clés complexes :
Des clés simples, genre "123", peuvent être devinées trop facilement.
- Change régulièrement les clés :
Pour éviter les fuites de données, pense à changer les clés de temps en temps, en re-chiffrant les données à chaque fois.
GO TO FULL VERSION