Pre­mière approche de chif­fre­ment sur IBM i DB2

Pre­mière approche de chif­fre­ment sur IBM i DB2

mer 25 septembre 2019 0 Par Ibmiiste

Sur IBM i, les don­nées sen­sibles sont sou­vent sto­ckées depuis des années dans des fichiers phy­siques deve­nus cri­tiques, sans chif­fre­ment ni contrôle fin des accès. Pour­tant, Db2 for i pro­pose plu­sieurs méca­nismes pour pro­té­ger ces infor­ma­tions, dont des fonc­tions SQL de chif­fre­ment simples à mettre en œuvre. Cet article pro­pose une pre­mière approche pra­tique, sans pré­tendre cou­vrir toutes les options de sécu­ri­té pos­sibles sur la plateforme.

Les exemples pré­sen­tés dans cet article ont été tes­tés sur IBM i 7.1, avec la base inté­grée Db2 for i. Ils res­tent en grande par­tie trans­po­sables sur des ver­sions plus récentes (7.2, 7.3, 7.4, 7.5), mais cer­tains détails peuvent varier selon votre environnement.

Pour­quoi chif­frer les don­nées sur IBM i ?

Les appli­ca­tions IBM i mani­pulent de plus en plus de don­nées sen­sibles : infor­ma­tions per­son­nelles, coor­don­nées ban­caires, don­nées de san­té, etc. Dans beau­coup de sys­tèmes his­to­riques, ces don­nées sont sto­ckées en clair dans les tables ou fichiers phy­siques, acces­sibles à de nom­breux pro­grammes batch, inter­faces 5250 ou outils de requête.

Même avec des pro­fils uti­li­sa­teurs bien gérés, des droits *PUBLIC limi­tés et des jour­naux d’audit acti­vés, les risques res­tent impor­tants : extrac­tion mas­sive par un compte puis­sant, copie de fichiers, fuite après sau­ve­garde non chif­frée. Le chif­fre­ment ajoute une couche de pro­tec­tion sup­plé­men­taire, en ren­dant l’information illi­sible sans la clé adéquate.

Dans cette pre­mière approche, on se concentre sur le chif­fre­ment au niveau colonne via SQL, sans abor­der les solu­tions plus avan­cées (Field­Proc, ges­tion de clés cen­tra­li­sée, HSM, etc.).

Pano­ra­ma rapide des options de chif­fre­ment Db2 for i

Avant d’entrer dans le code, il est utile de situer les prin­ci­pales options exis­tantes sur Db2 for i (liste non exhaus­tive, à adap­ter selon la ver­sion IBM i) :

  • Fonc­tions SQL de chif­fre­ment (ENCRYPT_xxx / DECRYPT_xxx)
    Chif­fre­ment au niveau colonne, pilo­té par des ins­truc­tions SQL, sou­vent le point d’entrée le plus simple pour un déve­lop­peur SQL/RPG.
  • Field Pro­ce­dures (Field­Proc)
    Méca­nisme Db2 for i per­met­tant de chif­frer auto­ma­ti­que­ment une colonne de table, de façon trans­pa­rente pour la plu­part des pro­grammes, au prix d’une confi­gu­ra­tion plus poussée.
  • APIs cryp­to­gra­phiques IBM i
    Ensemble d’APIs (Qc3…) offrant un contrôle fin du chif­fre­ment au sein des pro­grammes RPG, C, etc., avec une vraie logique de ges­tion de clés, mais une mise en œuvre plus technique.
  • Chif­fre­ment au niveau sys­tème / sto­ckage
    Solu­tions visant les biblio­thèques, fichiers, ASP ou l’IFS, utiles pour pro­té­ger les don­nées « au repos », mais qui ne rem­placent pas le chif­fre­ment logique des colonnes.

Dans cet article, on se limite volon­tai­re­ment aux fonc­tions SQL de chiffrement/déchiffrement pour illus­trer la démarche, sans entrer dans la ges­tion avan­cée des clés.

Pré-requis et contexte technique

Avant de tes­ter, quelques pré-requis à vérifier :

  • Ver­sion IBM i 7.1 minimum
  • Type de don­nées à chif­frer
    Les fonc­tions SQL de chif­fre­ment attendent un for­mat pré­cis (CHAR, VARCHAR, éven­tuel­le­ment CCSID par­ti­cu­lier). Il peut être néces­saire de cas­ter les colonnes avant chiffrement.
  • Droits et envi­ron­ne­ment
    Le déve­lop­peur doit dis­po­ser des droits néces­saires pour créer/altérer des tables, exé­cu­ter des fonc­tions SQL, et tes­ter sur un envi­ron­ne­ment non productif.

Exemple simple : chif­frer une colonne en SQL

1. Poser le mot de passe de chiffrement

Avant de chif­frer, tu poses le mot de passe de session :

SET ENCRYPTION PASSWORD = 'PHRASE_SECRETE';

L’instruction SET ENCRYPTION PASSWORD défi­nit un mot de passe de chif­fre­ment au niveau de la ses­sion SQL. Les fonc­tions de chif­fre­ment comme ENCRYPT_TDES uti­li­se­ront ce mot de passe par défaut, sauf si un autre est pas­sé expli­ci­te­ment en paramètre.

Avec WITH HINT pour ajou­ter une aide pour se sou­ve­nir du mot de passe

SET ENCRYPTION PASSWORD = 'PHRASE_SECRETE' WITH HINT 'Indice pour se souvenir';

2. Chif­frer la don­née avec ENCRYPT_TDES

SET ENCRYPTION PASSWORD = ‘PHRASE_SECRETE’;
INSERT INTO Client_Moyen_paiement VALUES(‘JOSHUA’, ENCRYPT_TDES(‘1111222233334444’));
  • ENCRYPT_TDES chiffre la chaîne pas­sée en para­mètre en uti­li­sant l’algorithme Triple DES (3DES).
  • Si tu ne passes pas de mot de passe en deuxième para­mètre, c’est le mot de passe de ses­sion défi­ni par SET ENCRYPTION PASSWORD qui est utilisé.
  • La colonne cor­res­pon­dante dans Client_Moyen_paiement doit être défi­nie avec une lon­gueur suf­fi­sante pour sto­cker la valeur chiffrée.

Dans cet exemple, la colonne NUM_CARTE ne stocke plus le numé­ro de carte en clair, mais le résul­tat de ENCRYPT_TDES. La valeur est illi­sible sans connaître le mot de passe de chif­fre­ment et uti­li­ser la fonc­tion de déchif­fre­ment correspondante.

Lec­ture de la don­née chif­frée avec DECRYPT_CHAR

Après avoir insé­ré la don­née chif­frée dans Client_Moyen_paiement, on peut la relire en clair avec DECRYPT_CHAR. On doit d’abord redé­fi­nir le même mot de passe de chif­fre­ment pour la session.

-- 1. Reposer le mot de passe de chiffrement pour la session
SET ENCRYPTION PASSWORD = 'PHRASE_SECRETE';

-- 2. Lire la donnée en clair à partir de la colonne chiffrée
SELECT
    CLIENT,
    DECRYPT_CHAR(MOYEN_PAIEMENT) AS NUM_CARTE_LISIBLE
FROM Client_Moyen_paiement
WHERE CLIENT = 'JOSHUA';

L’instruction SET ENCRYPTION PASSWORD doit uti­li­ser la même phrase secrète que celle employée lors du chif­fre­ment, sinon la fonc­tion DECRYPT_CHAR ne pour­ra pas retrou­ver la valeur d’origine. La table stocke tou­jours uni­que­ment le résul­tat de ENCRYPT_TDES, mais la requête SQL recons­ti­tue la don­née lisible à la volée pour les ses­sions qui connaissent le bon mot de passe.

Phrase secrète

  1. Évi­ter la phrase secrète en dur dans le code

Dans les exemples ci-des­sus, la phrase secrète appa­raît en clair pour des rai­sons péda­go­giques. En pro­duc­tion, il est for­te­ment recom­man­dé de ne jamais sto­cker cette pass­phrase en dur dans les sources SQL ou les scripts de déploie­ment, mais de la récu­pé­rer depuis un méca­nisme sécu­ri­sé (fichier de confi­gu­ra­tion pro­té­gé, variable d’environnement, coffre-fort à secrets, etc.).

  1. Limi­ter la visi­bi­li­té dans le code SQL Db2 for i

Sur IBM i, il est éga­le­ment pos­sible d’obfusquer le code SQL (fonc­tion WRAP) afin d’éviter que la phrase secrète appa­raisse en clair lorsqu’on récu­père le source d’une fonc­tion ou d’une pro­cé­dure. Cela ne rem­place pas une vraie ges­tion de clés, mais limite l’exposition acci­den­telle du secret dans les outils de développement.

Ci-des­sous le docu­ment qui a ser­vi à écrire cet article et pour aller plus loin :

Et pour aller encore plus loin, les docu­ments sui­vant dont un Red­book un peu ancien :

Pro­tec­ting i5/OS data with encryption

IBM Sys­tem i Secu­ri­ty : Pro­tec­ting i5/OS Data with Encryption