Written by

Quel que soit le pro­duit que vous déve­lop­pez, qu’il soit open source ou pro­prié­taire, vous en êtes rare­ment l’utilisateur·trice principal·e. Vous construi­sez des outils et des appli­ca­tions pour les autres. Et ces utilisateur·trice·s pro­duisent beau­coup de don­nées. Des don­nées sou­vent sen­sibles. Les récents scan­dales impli­quant les acteurs du Big Data nous montrent encore à quel point celles et ceux qui se servent de nos pro­duits ne savent pas com­ment se pro­té­ger.

Pour pré­ser­ver les don­nées qui nous sont confiées, nous n’a­vons pas d’autre choix que de nous appuyer sur des poli­tiques de chif­fre­ment. Whatsapp, Signal, Keybase, Nextcloud E2E module… tous ces outils uti­lisent de la cryp­to­gra­phie, de façon plus ou moins trans­pa­rente, nati­ve­ment, au cœur de leur code.

Nous don­nons de plus en plus sou­vent des confé­rences sur la sécu­ri­té infor­ma­tique et le chif­fre­ment dans le cadre de notre pro­gramme de Relations Développeur·euse·s. Il nous a sem­blé impor­tant d’en par­ler ici aus­si, pour ne pas limi­ter la dif­fu­sion des savoirs uni­que­ment au cercle, par­fois res­treint, des publics de confé­rences. Voici donc une intro­duc­tion à la cryp­to­gra­phie de zéro.


Vous avez dit « chiffrement » ?

Commençons par un rap­pel simple : le chif­fre­ment n’est rien d’autre que l’ob­fus­ca­tion d’un conte­nu. Cela signi­fie qu’un conte­nu chif­fré devient illi­sible pour qui n’en pos­sède pas la clef. Certains algo­rithmes ne fonc­tionnent que dans une direc­tion : le conte­nu chif­fré ne pour­ra pas reve­nir à son état d’o­ri­gine. Ce sont les algo­rithmes de sommes de contrôle, uti­li­sés uni­que­ment à des fins de véri­fi­ca­tion, pour garan­tir que les conte­nus n’ont pas été alté­rés. D’autres algo­rithmes vont pro­duire des conte­nus pou­vant être déchif­frés, et sont uti­li­sés pour garan­tir la sécu­ri­té des don­nées lors de leur trans­fert, ou de leur sto­ckage.

Tous s’ap­puient sur un élé­ment com­mun : la clef. Sans elle, pas de déchif­fre­ment ou de contrôle fiable du conte­nu, quel que soit la tech­nique de chif­fre­ment. Il s’a­git de la par­tie la plus cri­tique dans toute action cryp­to­gra­phique. La clef doit être gar­dée secrète, et doit être suf­fi­sam­ment robuste pour résis­ter à une attaque par force brute.

Les tech­niques de chif­fre­ment des don­nées numé­riques apportent une capa­ci­té à réa­li­ser des opé­ra­tions com­plexes, qui ne pour­raient pas être réa­li­sées manuel­le­ment. Elles garan­tissent la pro­tec­tion des conte­nus. Les algo­rithmes de chif­fre­ment s’ap­puient sur des pro­blèmes mathé­ma­tiques complexes1) pour for­ger des clefs résis­tantes, et (dé)chiffrer les don­nées.

Bien, comment ça fonctionne ?

Cette par­tie contient des expli­ca­tions théo­riques simples sur le fonc­tion­ne­ment des algo­rithmes de chif­fre­ment. N’hésitez pas à pas­ser à la sec­tion sui­vante si seule la mise en œuvre vous inté­resse 🙂

L’objectif d’un chif­fre­ment est de rendre son conte­nu inac­ces­sible aux yeux indé­si­rables. Depuis les débuts de l’his­toire du chif­fre­ment, la tech­nique n’a pas chan­gé : il s’a­git de sub­sti­tuer du conte­nu. Vous vous y êtes pro­ba­ble­ment déjà essayé, en jouant avec une roue de chif­fre­ment offerte dans Pif Gadget2).

Sur cette roue, si nous effec­tuons une rota­tion de trois points,A devient D, B devient E, et ain­si de suite. Le texte Hello World! devient alors KHOOR ZRUOG!.

Les algo­rithmes de chif­fre­ment modernes agissent de la même façon, en plus com­plexe tou­te­fois. Ils appliquent une série de sub­sti­tu­tion en cas­cade, en rem­pla­çant non plus des carac­tères, mais des blocs de données3) pour rendre les conte­nus chif­frés plus com­plexes à cas­ser par rétro-ingé­nie­rie.

Ces algo­rithmes néces­sitent cepen­dant d’être ini­tia­li­sés dans un état don­né. De cette façon, les risques de répé­ti­tion dans les motifs de sub­sti­tu­tion sont moins impor­tants en cas d’at­taques sur de grandes quan­ti­tés de don­nées ayant été chif­frées selon le même pro­cé­dé. Ce vec­teur d’i­ni­tia­li­sa­tion (IV) se doit donc d’être unique. Il assure qu’une même opé­ra­tion de chif­fre­ment ne don­ne­ra pas deux fois le même résul­tat sur un jeu de don­nées iden­tique. Mais pour s’as­su­rer de ce carac­tère unique, il nous faut des sources aléa­toires fiables.

Or nos ordi­na­teurs ne sont pas réel­le­ment impré­vi­sibles : leur desi­gn interne les pousse à repro­duire des motifs pré­cis au fil du temps. Pour évi­ter de tom­ber dans ce piège, les cryp­to­graphes ont créé des méthodes pour géné­rer des nombres aléa­toires suf­fi­sam­ment robustes au sens cryp­to­gra­phique du terme. Ces fonc­tions sont des géné­ra­teurs de nombre pseu­do aléa­toires cryp­to­gra­phi­que­ment purs (CSPRNG).

Comme vous pou­vez le consta­ter, les prin­cipes sont simples depuis le début (sub­sti­tuer des élé­ments) mais leur mise en œuvre est loin d’être facile. C’est la rai­son pour laquelle nous n’ef­fec­tuons jamais d’o­pé­ra­tion cryp­to­gra­phique « à la main ». Nous nous appuyons sur des biblio­thèques de chif­fre­ment, déve­lop­pées et véri­fiées par des cryp­to­graphes.

Tu sais garder un secret ?

Comme nous l’a­vons dit, la clef est l’élé­ment le plus cri­tique de la couche de cryp­to­gra­phie. Pour garan­tir la sécu­ri­té de vos don­nées, vous devez pro­té­ger cette clef. Dans la famille des algo­rithmes de chif­fre­ment / déchif­fre­ment, il existe deux grandes caté­go­ries selon la façons dont les clefs sont gérées.

La pre­mière caté­go­rie est celle des algo­rithmes à clef symé­trique, comme AES ou IDEA. Ils uti­lisent la même clef pour réa­li­ser à la fois les opé­ra­tions de chif­fre­ment et de déchif­fre­ment. Ils sont rapides, et peuvent agir sur de gros volumes de don­nées avec un coût de per­for­mance rai­son­nable. Mais vous devrez trans­mettre à la fois le conte­nu chif­fré et la clef pour per­mettre à une tierce per­sonne d’ac­cé­der au conte­nu. Si votre clef est inter­cep­tée durant le trans­fert, votre conte­nu n’est plus pro­té­gé.

L’autre caté­go­rie est celle des algo­rithmes à clef publique, ou asy­mé­triques, comme RSA. Ils fonc­tionnent avec des paires de clefs. L’une est publique : elle va ser­vir à chif­frer les don­nées que vous sou­hai­tez trans­mettre à son pro­prié­taire. La seconde est pri­vée, et ne ser­vi­ra qu’à votre des­ti­na­taire pour déchif­frer le conte­nu. Seul le pro­prié­taire d’une clef pri­vée peut donc reve­nir à la don­née initiale4). En revanche n’im­porte qui (pro­prié­taire inclus) peut envoyer du conte­nu chif­fré à des­ti­na­tion de cette clef pri­vée, en uti­li­sant la clef publique qui lui est asso­ciée. De telles opé­ra­tions ne sont pos­sibles qu’en s’ap­puyant sur des énigmes mathé­ma­tiques com­plexes, ce qui les rend par­ti­cu­liè­re­ment longues à réa­li­ser : elles s’ac­com­modent mal de gros volumes de don­nées.

Pour faci­li­ter les choses, et avoir le meilleur des deux mondes, nous avons sou­vent recours à l’en­cap­su­la­tion de clefs (key wrap­ping). Nous géné­rons un CSPRNG qui va ser­vir de clef unique pour chif­frer nos don­nées de façon symé­trique. Puis nous allons chif­frer cette clef unique avec la clef publique de notre des­ti­na­taire. Cette opé­ra­tion est rapide, parce qu’une clef, même robuste, reste une don­née rela­ti­ve­ment petite, et son chif­fre­ment ne néces­si­te­ra pas trop d’ef­forts. Nous empa­que­tons alors les deux élé­ments — la clef unique chif­frée, et le conte­nu chif­fré — et nous envoyons ou sto­ckons le tout.

3… 2… 1… Décollage !

Encore une fois, vous ne devez pas cher­cher à réa­li­ser vos opé­ra­tions de chif­fre­ment à la main, ou en inven­tant vos propres algo­rithmes. Les cryp­to­graphes tra­vaillent ensemble depuis des années pour consti­tuer un socle com­mun robuste et approu­vé. Les biblio­thèques d’abs­trac­tion récentes per­mettent de les uti­li­ser faci­le­ment, ne nous en pri­vons pas !

Le chiffrement pour tou·te·s : libsodium, la biblitohèque multi-plateforme

Tous les lan­gages de déve­lop­pe­ment ont leur(s) propre(s) bibliothèque(s) de cryp­to­gra­phie. Les uti­li­ser en revanche relève par­fois du défi. Elles néces­sitent sou­vent un gros bagage de connais­sances en cryp­to­gra­phie théo­rique, pour choi­sir les bons algo­rithmes et leurs bons para­mètres. Et il est par­fois dif­fi­cile de savoir quoi uti­li­ser, et à quel moment.

Mais ces outils pro­voquent un autre effet : ils néces­sitent que pour chaque lan­gage, une équipe de cryp­to­graphes les main­tienne, les teste, les sécu­rise. C’est une situa­tion qui est dif­fi­ci­le­ment tenable sur la durée, et qui peut pro­vo­quer l’ap­pa­ri­tion de failles dans les implé­men­ta­tions.

Une réponse au pro­blème serait de mutua­li­ser les efforts de déve­lop­pe­ment sur une biblio­thèque dédiée et agnos­tique de la pla­te­forme et du lan­gage. C’est exac­te­ment le pro­jet lib­so­dium ! Il se concentre sur l’u­ti­li­sa­bi­li­té au ser­vice des développeur·euse·s, en offrant une excel­lente abs­trac­tion. Il offre une réponse élé­gante à la pro­blé­ma­tique du choix en pré­sé­lec­tion­nant les bons algo­rithmes. Vous pou­vez l’u­ti­li­ser direc­te­ment dans votre pro­jet ou vous appuyer sur ses librai­ries tierces de pon­tage (bin­dings) pour l’in­ter­fa­cer avec votre lan­gage favo­ri !

Python

Pour géné­rer un CSPRNG, vous devriez plu­tôt vous appuyer sur la lib secrets qui offre une géné­ra­tion plus robuste que le tra­di­tion­nel os.random().


Pour chif­frer / déchif­frer les conte­nus, le paquet PyNaCl est un excellent choix :

Ruby

Utilisez RbNaCl pour exploi­ter la biblio­thèque lib­so­dium avec Ruby :

PHP

PHP offre l’ex­ten­sion lib­so­dium-php :


Vous pou­vez faci­le­ment ins­tal­ler l’ex­ten­sion depuis PECL dans votre compte always­da­ta avec la com­mande ad_install_pecl libsodium. Consultez notre docu­men­ta­tion sur l’ins­tal­la­tion des exten­sions PECL pour plus d’in­for­ma­tions.

Node.js®

Node.js® expose nati­ve­ment une excel­lente librai­rie de cryp­to­gra­phie via son module Crypto. Cela étant, s’ap­puyer sur lib­so­dium est pro­ba­ble­ment un meilleur choix. Vous pou­vez uti­li­ser libsodium.js, com­pi­lé vers WebAssembly depuis le code source de la biblio­thèque prin­ci­pale du pro­jet :

Java

Java dis­pose de la biblio­thèque lib­so­dium-jna :

Le côté obscur

Le plus tôt les don­nées sont chif­frées, meilleure sera leur pro­tec­tion dans votre archi­tec­ture. C’est le prin­cipe du chif­fre­ment point à point : les opé­ra­tions cryp­to­gra­phiques devraient s’exé­cu­ter dans le client. Heureusement, lib­so­dium est uti­li­sable dans un client mobile grâce à lib­so­dium-jni pour Android, et swift-sodium pour iOS5).

Le pro­blème reste la cible Web. WebCrypto est une bonne API bas-niveau, mais… et bien… elle reste bas niveau ¯\_(ツ)_/¯. Au quo­ti­dien, c’est inex­ploi­table, et nous avons besoin d’un outil plus effi­cace. Un autre pro­blème est lié à la nature même de JavaScript qui ne peut garan­tir, par son desi­gn, des pré­re­quis suf­fi­sant pour pro­té­ger l’en­vi­ron­ne­ment autour de la couche cryp­to­gra­phique.

Heureusement, nous dis­po­sons là encore de libsodium.js ! Son uti­li­sa­tion dans le navi­ga­teur est aus­si facile que :


Notez que vous pré­fè­re­rez sans doute l’u­ti­li­ser comme un module6) et l’embarquer via votre outil de pro­duc­tion comme Webpack ou Parcel.js.

Peut-être que vous aurez besoin d’un envi­ron­ne­ment encore plus sûr. Dans ce cas, vous pou­vez vous tour­ner vers Rust pour déve­lop­per le code métier de votre appli­ca­tion, et vous appuyer sur sodiu­moxide pour la par­tie cryp­to ! L’ensemble com­pile très bien vers WASM, et vous per­met d’embarquer votre code logique dans le navi­ga­teur, en ne conser­vant JavaScript que pour les tâches liées à l’in­ter­face.

Encore une chose…

La cryp­to­gra­phie est un tra­vail à plein temps. Elle néces­site des com­pé­tences mathé­ma­tiques fortes dans son approche théo­rique. Nous n’a­vons pas cou­vert ici ses autres champs d’ap­pli­ca­tion comme :

  • échan­ger et sto­cker des clefs asy­mé­triques ;
  • uti­li­ser l’al­go­rithme de Diffie-Hellman pour for­ger une clef symé­trique pri­vée ;
  • signer un conte­nu pour l’au­then­ti­fier ;
  • etc.

Encore une fois : quelle que soit votre tâche, appuyez-vous sur une biblio­thèque cryp­to­gra­phique d’abs­trac­tion. Ne cher­chez jamais à conce­voir vos propres algo­rithmes à moins d’être un·e cryp­to­graphe confirmé·e.

Quoi que vous cher­chiez à pro­té­ger, envi­sa­gez tou­jours le pire scé­na­rio pos­sible. Aucune pro­tec­tion n’est assez robuste pour résis­ter à l’é­preuve du temps. Appuyez-vous tou­jours sur des algo­rithmes recon­nus avec de hauts stan­dards de résis­tance, comme de longues clefs ECC ou RSA7). Utilisez des clefs uniques. Utilisez des nonces. Évitez de réuti­li­ser ces élé­ments. N’hésitez jamais à mettre à jour votre couche cryp­to­gra­phique pour amé­lio­rer sa sécu­ri­té quand une faille est décou­verte. Nous avons tous droit à l’er­reur, mais nous devons à nos utilisateur·trice·s de cor­ri­ger chaque pro­blème trou­vé qui les met­trait en dan­ger !

Dans le cas d’une appli­ca­tion ser­veur impor­tante, envi­sa­gez les dis­po­si­tifs maté­riels de ges­tion de clefs. Les modules HSM (Hardware Security Module) vous per­mettent d’ex­ter­na­li­ser les opé­ra­tions cryp­to­gra­phiques. Ils vous per­mettent de gar­der les clefs en dehors du sys­tème de fichiers. Elles ne sont ain­si pas com­pro­mises en cas d’at­taque. Ces modules sont désor­mais acces­sibles à des prix abor­dables grâce à des pro­jets open source8).


Gageons que cette (pas si courte) intro­duc­tion à la Cryptographie vous aura quelque peu éclairé·e. Si vous vou­lez aller plus en détail dans le sujet, vous pou­vez trou­ver une ver­sion live sur YouTube de la confé­rence asso­ciée au sujet que je (m4dz) donne régu­liè­re­ment.

Nous serons d’ailleurs pré­sents avec ce talk à Techorama, Netherlands et à PiterPy, Saint Petersburg avec sa toute nou­velle ver­sion !

Vous êtes convaincu·e·s de l’im­por­tance de la cryp­to­gra­phie dans votre pro­jet ? Vous sou­hai­tez l’u­ti­li­ser dans votre plan d’hé­ber­ge­ment always­da­ta ? Demandez-nous de vous four­nir un device HSM sur votre plan dédié, et nous nous ferons un plai­sir de vous le pro­cu­rer !

Notes   [ + ]

1. comme les nombres pre­miers, ou les courbes ellip­tiques
2. si vous êtes aus­si vieux que moi, sinon c’é­tait pro­ba­ble­ment Picsou Magazine
3. par exemple des blocs d’une lon­gueur de 4096 octets
4. puisqu’il est le seul à pos­sé­der la clef, vu qu’elle est pri­vée, vous sui­vez ?
5. Apple a par ailleurs récem­ment don­né accès à sa biblio­thèque Cryptokit, pour per­mettre un accès aux pri­mi­tives cryp­to­gra­phiques direc­te­ment dans le code Swift natif
6. comme avec Node.js ci-des­sus
7. les clefs ECC 256 bits sont consi­dé­rées aus­si robustes que des clefs RSA 3078 bits
8. comme les clefs HSM Nitrokey