GnuPG, OpenPGP.js & cie : quoi de neuf ?

58
15
avr.
2018
Sécurité

Le 8 mars 2018, la version 3.0.0 de la bibliothèque OpenPGP.js sortait. Elle implémente le format OpenPGP en JavaScript et est disponible sous licence LGPL 3.0. C’est l’occasion de présenter cette bibliothèque et les nouveautés apportées par cette version. C’est surtout un très bon prétexte pour parler du standard OpenPGP lui‐même, de ses principales implémentations et de ses évolutions futures.

Sommaire

OpenPGP

OpenPGP est un standard IETF visant à garantir l’interopérabilité entre logiciels de sécurisation de données, aussi bien en repos qu’en transit. Le nom vient du logiciel PGP (Pretty Good Privacy), écrit au début des années 1990 par Phil Zimmermann.

OpenPGP n’est pas un protocole, c’est un format (pensez, par exemple, à la différence entre HTTP et HTML). Le standard décrit le format des données manipulées par PGP (ou tout autre logiciel compatible avec ce standard). Il ne se préoccupe pas de savoir comment ces données sont échangées d’un logiciel à un autre — que cela se fasse par courrier électronique, par copie de fichiers à travers le sneakernet, ou par IP sur transporteurs aviaires, c’est indifférent pour OpenPGP.

Cette distinction est fondamentale et explique, entre autres, pourquoi OpenPGP ne permet pas la confidentialité persistante (forward privacy en VO), cette fonctionnalité nécessitant un échange synchrone entre les deux parties à la communication (donc un protocole de communication entre les logiciels aux deux extrémités).

Le format OpenPGP peut être utilisé pour :

  • chiffrer des données afin de garantir leur confidentialité : seules les personnes autorisées peuvent lire les données ;
  • signer des données afin de garantir leur intégrité — personne ne peut modifier les données subrepticement — et leur authenticité : on peut vérifier que les données proviennent bien de leur émetteur supposé ;
  • authentifier des utilisateurs.

Les briques élémentaires du format OpenPGP sont les paquets. Toutes les données manipulées par un logiciel comme PGP sont représentées sous la forme de paquets. Il existe des paquets pour représenter, par exemple, une clef cryptographique, un nom d’utilisateur, une signature, ou encore un « blob » de données arbitraires (typiquement le texte chiffré et/ou signé).

Une suite de paquets constitue un message OpenPGP. Par exemple, un courrier électronique chiffré, sous sa forme la plus simple, est un message constitué d’un paquet contenant une clef de session symétrique (chiffrée avec la clef publique du destinataire) suivi d’un paquet contenant le corps du courrier électronique (chiffré avec la clef de session). Ce message au format OpenPGP sera probablement acheminé avec le protocole SMTP, IMAP, ou POP3.

Un bref historique d’OpenPGP

La première version du standard est sortie en 1996 (RFC 1991), elle décrit le format des messages de PGP 2.6. Deux ans plus tard paraît la seconde version (RFC 2440), basée sur PGP 5 et qui introduit plusieurs changements majeurs (dont le nom OpenPGP lui‐même, qui ne figurait pas dans le RFC 1991) :

  • l’algorithme de condensation MD5 est déclaré obsolète, SHA-1 est recommandé à la place ;
  • le format de clef v3, utilisant des empreintes MD5, est remplacé par un nouveau format v4, utilisant des empreintes SHA-1 ;
  • il est désormais possible d’ajouter des sous‐clefs à une clef maître (ou primaire) ;
  • on peut désormais certifier une clef avec une trust signature.

En 2007, le standard est rafraîchi sous la forme du RFC 4880. Les principaux changements sont l’introduction officielle des algorithmes de chiffrement AES (la compétition AES n’était pas encore terminée lors de la publication du RFC 2440) et des algorithmes de condensation de la famille SHA-2. Depuis, deux autres RFC sont venus enrichir le standard avec des algorithmes supplémentaires : le RFC 6637 (algorithmes de cryptographie à clef publique basés sur les courbes elliptiques) et le RFC 5581 (algorithme de chiffrement Camellia).

Les nouveautés à venir

Une nouvelle révision du standard, temporairement désignée RFC 4880bis, est aujourd’hui en cours de préparation. Les principaux changements prévus, tels qu’ils figurent dans le dernier brouillon, sont :

  • un nouveau format de clef, v5, associé à des empreintes SHA-256 ;
  • un nouveau paquet pour les données chiffrées en mode « chiffrement authentifié » (AEAD, Authenticated Encryption with Associated Data), qui remplacera l’actuel système MDC (Modification Detection Code) ;
  • quelques changements parmi les algorithmes « obligatoires » (MtI, Mandatory-to-Implement) — notamment, AES remplace 3DES comme algorithme symmétrique obligatoire ;
  • les additions du RFC 6637 (cryptographie ECC) sont incorporées, et les courbes Brainpool (RFC 5639) et Curve25519 (RFC 7748) sont ajoutées.

Les changements concernant les algorithmes obligatoires ou recommandés sont somme toute assez évidents et n’appellent guère de commentaires. Nous aborderons le nouveau mode AEAD un peu plus loin, avec OpenPGP.js. Pour l’instant, attardons-nous sur le premier point, l’introduction du nouveau format de clef.

L’objectif principal du groupe de travail à cet égard était de se débarrasser de SHA-1. Cet algorithme de condensation est au cœur du RFC 4880, car il sert à calculer les empreintes des clefs au format V4. La résistance aux collisions n’est pas nécessaire dans ce cas de figure et les empreintes V4 ne sont pas menacées par les récentes attaques contre SHA-1, mais l’élimination de SHA-1 était jugée nécessaire pour ne pas donner l’impression que le standard OpenPGP devenait obsolète.1

Pour introduire un nouvel algorithme de calcul des empreintes tout en maintenant la compatibilité avec le standard et le code existant, le groupe de travail a convenu que la meilleure solution était de laisser le format V4 en l’état (toujours dépendant de SHA-1, donc) et d’introduire un nouveau format V5, dont les empreintes seraient calculées par un algorithme plus moderne.

Malheureusement, si tout le monde était d’accord sur le principe, le groupe de travail OpenPGP a perdu beaucoup de temps sur les détails, notamment sur le choix de l’algorithme « moderne » à utiliser. Il a même été envisagé de définir un format d’empreinte flexible, où le premier octet de l’empreinte indiquerait l’algorithme utilisé (ce qui aurait permis de changer plus facilement d’algorithme par la suite, sans avoir à créer un nouveau format de clef).

Les tergiversations du groupe autour de cette seule question ont fini par agacer l’IETF (qui n’aime pas trop les groupes de travail qui n’avancent pas) et, sous la pression d’une fermeture imminente du groupe, les participants se sont finalement mis d’accord pour choisir SHA-256, pour les raisons suivantes :

  • les travaux réalisés dans le cadre de la compétition SHA-3 ont montré que SHA-2 était beaucoup plus solide qu’on ne le pensait, réduisant l’intérêt de SHA-3 ;
  • SHA-256 est déjà pris en charge par toutes les implémentations existantes du standard (les signatures utilisant SHA-256 sont monnaies courantes depuis plusieurs années, c’est même l’algorithme de condensation par défaut de GnuPG depuis 2009), contrairement à SHA-3 — réutiliser SHA-256 réduira la charge des implémenteurs et facilitera la transition vers la nouvelle version du standard ;
  • SHA-256 peut être implémenté de manière efficace, même sur du matériel limité ;
  • une empreinte SHA-256 ne fait « que » 32 octets, ce qui est une augmentation raisonnable par rapport aux 20 octets d’une empreinte SHA-1 ; c’est important pour deux raisons :
    • ça évite de faire exploser la taille des signatures générées avec des clefs ECC (le problème ne se pose guère pour les signatures RSA, les clefs RSA modernes étant déjà beaucoup plus longues que le condensat de toute façon),
    • ça reste assez court pour que la représentation hexadécimale de l’empreinte (64 caractères) soit exploitable par des humains.

Malgré cette décision, l’IETF est restée sur son impression initiale et, considérant que le groupe de travail n’était pas assez actif, elle l’a formellement fermé quelques mois plus tard. Concrètement, ça ne change pas grand‐chose : la liste de discussion openpgp est restée ouverte et les travaux y continuent. L’existence formelle d’un groupe de travail n’est d’ailleurs pas une condition nécessaire à la publication d’un RFC.

Quelques implémentations d’OpenPGP

PGP

Impossible de ne pas dire quelques mots à propos de PGP, l’implémentation originale sans laquelle le standard n’existerait pas. Depuis la sortie de PGP 1.0 en 1991, ce logiciel a connu une histoire mouvementée et fascinante qui mériterait largement qu’on lui consacre un article à part entière, mais on se contentera ici d’en donner quelques faits marquants.

PGP a connu six éditeurs successifs :

  • Philip Zimmermann (PRZ), lui‐même, à titre individuel, à partir de 1991 ;
  • ViaCrypt, à qui PRZ concède en 1993 le droit exclusif de vendre une version commerciale de PGP ;
  • PGP Inc., société fondée et dirigée par PRZ en 1996 à l’issue de ses démêlés judiciaires (on y revient dans un instant), qui rachète à ViaCrypt ses droits sur PGP ;
  • Network Associates Inc. (NAI), qui acquiert PGP en décembre 1997 ; PRZ et son équipe de PGP Inc. deviennent employés de NAI ;
  • PGP Corp, qui rachète PGP à Network Associates Inc. en 2002 ;
  • et finalement Symantec, qui rachète PGP Corp en 2010. PGP fait aujourd’hui partie de la gamme de produits Encryption Family chez Symantec, même si le nom PGP lui‐même n’apparaît quasiment plus.

La publication des premières versions de PGP a valu à Philip Zimmermann deux poursuites judiciaires distinctes.

L’une émane du gouvernement américain, en la forme du service des douanes de San José qui, à partir de septembre 1993 reproche à Philip Zimmermann, à ViaCrypt et à toute autre personne ou entité agissant pour le compte de PRZ, d’avoir enfreint les régulations américaines en matière d’exportations d’armement (ITAR), les logiciels de cryptographie étant considérées comme des munitions de guerre et PGP ayant rapidement fuité hors des frontières américaines, notamment via Usenet.

L’action du gouvernement américain s’inscrit dans le cadre de ce qu’on a appelé la Crypto War, une série d’efforts visant à limiter l’accès du public à la cryptographie « forte » et/ou à imposer l’introduction de portes dérobées au bénéfice des services gouvernementaux (entre autres exemples de ces efforts : la proposition de loi S.266 qui est justement celle qui décida PRZ à diffuser PGP, ou le projet Clipper). On devrait maintenant parler de Crypto War I, puisque nous sommes actuellement en plein dans la Crypto War II.

Les charges contre Zimmermann ont finalement été abruptement abandonnées en janvier 1996. De l’avis des juristes qui se sont mobilisés pour PRZ, si l’affaire était allée jusqu’à un procès, l’issue n’aurait de toute façon pas fait un pli, les actes de PRZ (poster un code source sur les réseaux BBS) relevant indéniablement de la liberté d’expression protégée par le premier amendement de la constitution américaine.

La seconde poursuite contre PRZ émane de RSA Data Security Inc., détenteur d’une partie des droits sur le brevet RSA, qui reproche à PRZ de diffuser un logiciel mettant en œuvre RSA sans disposer d’une licence l’y autorisant. PRZ avait cru se mettre à l’abri de ce genre de soucis en insérant dans la documentation de PGP 1.0 le disclaimer suivant :

The RSA public key cryptosystem […] is patented by MIT (U.S. patent #4,405,829, issued 20 Sep 1983). A company called Public Key Partners (PKP) holds the exclusive commercial license to sell and sub‐license the RSA public key cryptosystem. […] The author of this software implementation of the RSA algorithm is providing this implementation for educational use only. Licensing this algorithm from PKP is the responsability of you, the user, not Philip Zimmermann, the author of this software implementation. The author assumes no liability for any breach of patent law resulting from the unlicensed use by the user of the underlying RSA algorithm used in this software.

Mais RSA Data Security Inc. (principal membre de Public Key Partners) ne l’entendait pas de cette oreille et va contraindre PRZ à cesser de diffuser PGP. Zimmermann accepte, sachant que cela ne compromet en rien la diffusion de PGP : le logiciel est déjà en libre circulation sur Internet et interdire à PRZ de le diffuser n’empêchera pas ceux qui en ont déjà obtenu une copie de la diffuser à leur tour… Probablement l’un des premiers épisodes de la longue série « Le monde de la propriété intellectuelle découvre Internet ».

Pour les versions ultérieures de PGP, le problème du brevet RSA sera résolu de deux façons :

  • PGP 2.4 est vendu par ViaCrypt, qui a acheté une licence pour RSA auprès de RSA Data Security Inc. ;
  • PGP 2.5 (et ultérieur) utilise RSAREF, une implémentation de RSA provenant du MIT. Ce dernier détenant toujours une partie des droits sur le brevet RSA, RSAREF n’est pas considérée comme violant ledit brevet. Cette position est initialement contestée par RSA Data Security Inc., qui n’insistera pas : s’attaquer au MIT n’est pas une mince affaire, contrairement à l’attaque d’un développeur isolé.

Bien entendu, cela ne concerne que les versions de PGP diffusées sur le sol américain. Dans le reste du monde (où le brevet sur RSA n’est pas applicable), les versions internationales de PGP continuent à utiliser l’implémentation originale de PRZ au lieu de RSAREF, dont la licence interdit l’export hors des États‐Unis.

GnuPG

GnuPG ou GNU Privacy Guard (parfois improprement appelé gpg, qui est en fait le nom du principal binaire exécutable du projet) est un logiciel libre de chiffrement et signature implémentant, entre autres, le standard OpenPGP. Le projet a été initié en 1997 par Werner Koch en réponse à un appel de Richard Stallman qui souhaitait que le projet GNU se dotât d’une alternative libre à PGP. C’est aujourd’hui l’implémentation libre de référence du standard OpenPGP.

Le projet existe en trois branches parallèles :

  • la branche 1.4.x, largement désuète mais néanmoins activement maintenue par souci de compatibilité — c’est la seule branche aujourd’hui capable d’inter‐opérer encore avec PGP 2.x, les branches ultérieures ayant cessé de prendre en charge le RFC 1991 pour simplifier la base de code ;
  • la branche 2.2.x, la branche stable ;
  • la future branche 2.3.x, la branche de développement (qui n’a pas encore donné lieu à une publication).

Les branches 2.0.x (ancienne branche stable) et 2.1.x (ancienne branche de développement) ne sont plus maintenues.

GnuPG est à la fois un outil directement utilisable en lui‐même (du moins pour les utilisateurs que la ligne de commande ne rebute pas), et un back‐end pour des logiciels en mode graphique tels que :

  • Enigmail, un greffon pour le client de messagerie Thunderbird ;
  • GPA (GNU Privacy Assistant), le frontal standard du projet ;
  • Seahorse, un outil de chiffrement et de gestion de clefs pour GNOME ;
  • KGpg, l’équivalent pour KDE ;
  • etc.

GnuPG sert aussi de back‐end à plusieurs bibliothèques ou modules dans divers langages de programmation :

  • la bibliothèque GpgME, en C ;
  • le module Mail::GPG de Perl ;
  • le module GnuPG de PHP ;
  • etc.

L’omniprésence de GnuPG ne doit toutefois pas occulter qu’il ne s’agit pas de la seule implémentation libre du standard OpenPGP. Au fil du temps, des implémentations complètement indépendantes ont été développées.

RNP (ex OpenPGPSDK / NetPGP)

La plupart des fonctionnalités de GnuPG ne sont accessibles que via ses binaires exécutables (gpg pour tout ce qui concerne OpenPGP). Les fonctions cryptographiques de base sont regroupées dans une bibliothèque C à part, libgcrypt, qui est utilisée par d’autres projets indépendamment de GnuPG. Cependant, les fonctions de plus haut niveau sont implémentées directement dans les binaires exécutables, ce qui ne facilite pas forcément leur réutilisation dans d’autres projets.

La manière recommandée d’utiliser les fonctionnalités de GnuPG à partir d’un autre projet est d’invoquer le binaire gpg. Le programme dispose d’un mode non interactif spécialement conçu pour les cas où il est exécuté par un autre programme plutôt que par un utilisateur. La bibliothèque GpgME toute entière est en fait un wrapper autour de gpg, présentant aux développeurs des fonctions C « classiques » qui, pour la plupart, appellent gpg en arrière‐plan pour accomplir leur tâche.

Cette approche ne plaît pas à tout le monde et l’idée d’une « vraie » bibliothèque OpenPGP (c.‐à‐d., pas un wrapper autour de gpg) n’est pas nouvelle. La dernière incarnation de cette idée est RNP, qui se présente comme « a C library approach to OpenPGP ».

RNP est développé par l’entreprise Ribose et est un fork de NetPGP, une implémentation d’OpenPGP initiée en 2009 par des développeurs de NetBSD. NetPGP lui‐même est bâti sur OpenPGP-SDK, une bibliothèque OpenPGP publiée quelques mois auparavant par Ben Laurie et Rachel Willmer.

Aujourd’hui, tant OpenPGP-SDK que NetPGP sont au point mort. Le site officiel d’OpenPGP-SDK ne répond plus, et bien qu’une copie des sources soit toujours disponible sur GitHub et dans le CVS de NetBSD, elles n’ont plus été modifiées depuis 2011. La dernière version de NetPGP remonte à 2014 et le CVS ne témoigne d’aucune activité au cours des cinq dernières années. L’implémentation est pourtant loin d’être complète, des fonctionnalités aussi élémentaires que le chiffrement pour plusieurs destinataires étant toujours absentes. Il semble assez évident que le projet est abandonné, en dépit de la FAQ qui prétend qu’il est toujours « activement maintenu et développé » — mais la FAQ elle‐même n’a pas été mise à jour depuis 2010…

Le développement de RNP est, lui, bien actif. Depuis son démarrage fin 2016, le projet comble progressivement les lacunes de son prédécesseur. Cependant, il n’est pas encore pleinement compatible avec le standard, n’a pas été audité et souffre de quelques bogues récurrents. Le fondateur de Ribose, Ronald Tse, est activement impliqué dans l’élaboration du RFC 4880bis au sein du groupe de travail OpenPGP. Dans l’ensemble, RNP est certainement un projet à suivre.

Autres implémentations

Voici quelques autres projets implémentant le standard OpenPGP ; les projets explicitement ou manifestement abandonnés ne sont pas inclus :

  • NeoPG, un fork de GnuPG converti en C++11 et utilisant Botan plutôt que libgcrypt comme bibliothèque cryptographique ; le projet souhaite notamment revenir à l’architecture monolithique de GnuPG 1.x (suppression des démons de GnuPG 2.x) et globalement à « dégrossir » le code (de nombreuses fonctionnalités introduites dans les versions modernes de GnuPG ont déjà été supprimées) ;
  • OpenPGP-PHP, une implémentation en pur PHP, à ne pas confondre avec php-gnupg qui est une bibliothèque de liaison (binding) de GpgME pour PHP ;
  • hOpenPGP, une implémentation en Haskell ;
  • Bouncy Castle, une bibliothèque cryptographique disponible en Java et en C#, fournissant (entre beaucoup d’autres choses) une implémentation du RFC 4880 ;
  • ObjectivePGP, une implémentation en Objective C pour macOS et iOS, non libre qui sert notamment de base à Privacy, une messagerie PGP pour iOS (également non libre, apparemment) ; on appréciera les ambitions du développeur : I believe I can revolutionize how PGP is used ;
  • Swift-PGP, une implémentation en Swift encore très rudimentaire (en particulier, elle ne prend pas encore en charge les opérations de chiffrement, seulement les opérations de signature) ; licence « non encore décidée » (donc, non libre) ;
  • Cryptlib, une bibliothèque cryptographique en C par Peter Gutmann fournissant, entre autres, une implémentation OpenPGP ;
  • Crypt::OpenPGP, une implémentation en Perl.

OpenPGP.js

La bibliothèque OpenPGP.js est issue et inspirée de plusieurs projets défunts. Le dénominateur commun de ces derniers était l’objectif d’implémenter tout ou partie du standard OpenPGP en JavaScript pour faire du chiffrement côté client dans les webmails. Parmi ces projets abandonnés, citons GPG4Browsers.

OpenPGP.js était dirigé par Tankred Hase, cofondateur de Whiteout. Au cours de l’été 2016, il a été remplacé par Bart Butler, directeur technique de Proton Technologies AG, l’entreprise derrière ProtonMail. Outre ce webmail, la bibliothèque est utilisée par des projets tels que Hoodiecrow, Mailvelope, la plate‐forme encrypt.to ou l’extension PGP-Anywhere pour le navigateur Google Chrome.

En termes de sécurité, l’utilisation d’un langage interprété comme JavaScript n’est pas anodine. En effet, pour un programme compilé tel que GnuPG, l’exécution est censée être sure si le système hôte n’est pas compromis. Dans le cas d’OpenPGP.js, il faut également que le moteur JavaScript — qui réside en général dans le navigateur — ne soit pas compromis. La surface d’attaque est ainsi plus grande.

L’option openpgp.config.aead_protect, anatomie d’une mauvaise idée

Une spécificité d’OpenPGP.js que ses développeurs prennent soin de mettre en avant est la possibilité d’utiliser AES-GCM pour le chiffrement symétrique, qui « rend(rait) le chiffrement trente fois plus rapide » (a priori, comparé à AES-CFB, bien que ce ne soit pas explicite) :

The library implements the IETF proposal for authenticated encryption using native AES-GCM. This makes symmetric encryption about 30× faster on supported platforms. Since the specification is not finalized and other OpenPGP implementations haven’t adopted it yet, the feature is currently behind a flag. You can activate it by setting openpgp.config.aead_protect = true. Note: activating this setting can break compatibility with other OpenPGP implementations, so be careful if that’s one of your requirements.

Cela semble alléchant, mais utiliser cette fonctionnalité revient en fait à se tirer une balle dans le pied et il est important de comprendre pourquoi. C’est l’objet de cette section. Cela va également nous fournir l’occasion de revenir sur l’une des principales nouveautés de la prochaine version du standard OpenPGP : le chiffrement authentifié.


TL;DR: La « proposition IETF » mentionnée est une version préliminaire qui n’a aucune chance d’être intégrée telle quelle dans le standard, le groupe de travail OpenPGP ayant depuis formulé une proposition différente. Conséquemment, elle ne sera jamais prise en charge par aucune autre implémentation d’OpenPGP. Si vous utilisez cette « fonctionnalité », vos messages ne seront pas lisibles par d’autres implémentations d’OpenPGP (c’est une certitude, pas seulement une possibilité comme le laisse entendre l’avertissement ci‐dessus) et, pire encore, il est probable qu’ils ne soient même pas lisibles avec les versions futures d’OpenPGP.js. Laissez openpgp.config.aead_protect à false !


OpenPGP et l’intégrité des messages chiffrés

Une des garanties que l’on attend d’un format comme OpenPGP est l’assurance qu’un message chiffré n’a pas été modifié en cours de route (c’est l’intégrité du message). La signature du message est un moyen d’offrir cette garantie (toute modification du message invalidant la signature), mais elle n’est pas toujours désirable (notamment parce que la signature lie le message à son émetteur/signataire, ce qui n’est pas forcément dans l’intérêt de ce dernier — pensez à un lanceur d’alerte par exemple).

OpenPGP offre donc, indépendamment des signatures, un système de vérification de l’intégrité d’un message chiffré, le Modification Detection Code (MDC ci‐après), dont le principe est le suivant : lors de la création d’un message chiffré, l’émetteur calcule un condensat cryptographique du texte clair, l’ajoute à la fin du texte, et c’est l’ensemble (texte clair, condensat) qui est alors chiffré. À la réception, le destinataire déchiffre le message, calcule à son tour un condensat sur le texte clair et le compare au condensat reçu : si les deux divergent, le message a été modifié.

Ce principe, connu sous le nom générique de MAC-then-Encrypt (bien que ce terme soit impropre dans le cas du MDC d’OpenPGP, le MDC n’étant pas un MAC), n’a plus les faveurs des cryptographes de nos jours. Son problème fondamental est qu’il impose, du côté du destinataire, de déchiffrer le message avant de pouvoir vérifier qu’il n’a pas été modifié. Entre autres conséquences, cela laisse la porte entr’ouverte à de potentielles attaques « à textes chiffrés choisis » (chosen‐ciphertext attacks) comme celle de Jallad, Katz et Schneier (2002). Il est généralement admis aujourd’hui qu’il faut privilégier le principe Encrypt‐then‐MAC (calculer le MAC sur le texte chiffré, permettant au destinataire de vérifier l’intégrité avant toute tentative de déchiffrement) ou, mieux, un mode d’opération combinant chiffrement et authentification (Authenticated Encryption with Associated Data ou AEAD).

Les propositions du groupe de travail OpenPGP

Prenant acte du consensus des cryptographes en faveur d’AEAD, le groupe de travail OpenPGP à l’IETF a commencé à étudier la question lors de la réunion IETF ’93 en juillet 2015. Et, quelques mois plus tard, Bryan Ford publiait un brouillon proposant la création d’un nouveau type de paquet spécialement conçu pour l’utilisation d’algorithmes permettant le chiffrement authentifié. Dans ce brouillon initial, un AEAD Encrypted Data Packet est identifié par le code 20 et est formé par la simple concaténation du vecteur d’initialisation, du texte chiffré proprement dit et du code d’authentification.

L’objectif du brouillon de Bryan Ford était de servir de base de discussion pour le groupe de travail OpenPGP, ce qui fut notamment le cas lors de la réunion IETF ’94. Mais il n’a jamais été prévu qu’il aille plus loin que ça, et le brouillon a expiré normalement sans jamais devenir un RFC. Les idées qu’il a suscitées devant ensuite trouver leur place dans le futur RFC 4880bis, dont le chantier venait de commencer.

Par la suite, Brian Carlson a formulé une nouvelle proposition qui a été intégrée dans le brouillon actuel du RFC 4880bis. Dans sa forme actuelle, elle reprend l’idée de Bryan Ford de créer un nouveau type de paquet (toujours avec le code 20), mais avec une composition différente :

  • un octet représentant le numéro de version du format de paquet (pour pouvoir faire évoluer le format si nécessaire) ;
  • un octet indiquant l’algorithme symétrique avec lequel les données du paquet sont chiffrées (AES128, AES192, Camellia, etc.) ;
  • un octet indiquant le mode AEAD choisi (cf. ci‐dessous) ;
  • le vecteur d’initialisation ;
  • le texte chiffré proprement dit ;
  • le code final d’authentification.

Deux modes AEAD sont pour l’instant retenus : EAX et OCB. Toutefois, OCB fait l’objet de brevets aux États‐Unis (7,949,129 et 8,321,675), et son maintien dans le RFC final n’est pas garanti, tous les membres du groupe de travail OpenPGP n’étant pas favorables à l’inclusion d’un algorithme breveté. À noter que Philip Rogaway, auteur d’OCB et détenteur des brevets en question, accorde une licence d’utilisation à tout projet sous licence libre, ce qui devrait a priori lever tout obstacle à l’implémentation d’OCB dans GnuPG ou OpenPGP.js — mais le groupe de travail pense aussi aux implémentations propriétaires du standard, comme Symantec PGP par exemple.

Aujourd’hui, à l’incertitude sur le sort du mode OCB près, la forme actuelle du AEAD Encrypted Data Packet semble faire consensus au sein du groupe de travail et elle devrait probablement se retrouver sans trop de modifications dans la version finale du RFC 4880bis.

Le système MDC actuel, de son côté, sera maintenu pour des raisons de compatibilité, mais il n’est pas prévu de le faire évoluer. L’idée est que les implémentations cessent progressivement d’utiliser le mode de chiffrement actuel (avec son système MDC) et basculent vers le chiffrement AEAD qui, à terme, devrait devenir ubiquitaire.

Et OpenPGP.js là-dedans ?

Début 2016, les développeurs d’OpenPGP.js ont pris connaissance du brouillon initial de Bryan Ford et ont pris l’initiative de l’implémenter, ainsi qu’ils l’ont signalé sur la liste de discussion gnupg-devel :

For the sake of experimenting and to gain insight on the IETF draft, OpenPGP.js will go ahead and merge the AEAD pull request based on the current AES-GCM proposal. The feature will be hidden behind a flag and disabled by default. But it will allow applications that do not require interoperability to opt‐in and experiment with the security/performance benefits.

Il n’y a évidemment aucun mal à expérimenter avec les brouillons IETF. C’est même, entre autres, à ça qu’ils servent. Mais l’approche d’OpenPGP.js est ici problématique à mon sens, pour plusieurs raisons :

  • il y a un double discours de la part des développeurs d’OpenPGP.js : d’un côté (dans les discussions avec GnuPG) c’est une « expérimentation » visant à améliorer la proposition de standard, de l’autre (dans le README du projet) c’est une fonctionnalité offrant un gain sensible de performances (« 30 fois plus rapide ») ;
  • initialement la fonctionnalité était activée par défaut, jusqu’à ce qu’un développeur réalise que les gens s’attendent probablement à ce qu’une bibliothèque appelée OpenPGP.js soit par défaut compatible avec le standard OpenPGP ;
  • il a fallu un an avant qu’un avertissement ne soit ajouté au README du projet pour prévenir que aead_protect « peut casser la compatibilité avec d’autres implémentations », alors même qu’il est certain qu’un message chiffré par OpenPGP.js avec cette fonctionnalité activée est et sera toujours illisible par toutes les autres implémentations ;
  • le standard OpenPGP prévoit des codes spécifiques pour les paquets non standard (codes 60 à 63, réservées aux usages « privés ou expérimentaux ») ; indépendamment du réel statut de la fonctionnalité aead_protect (destinée à expérimenter et améliorer le brouillon IETF, ou destinée aux utilisateurs désireux de gagner en performances et n’ayant pas besoin de compatibilité avec les autres implémentations), les développeurs auraient dû utiliser un de ces codes au lieu de décider unilatéralement d’utiliser le code 20 pour le nouveau AEAD Encrypted Data Packet.

Ce dernier point va immanquablement poser un gros problème dans un futur proche. La version actuelle du brouillon IETF pour le RFC 4880bis décrit un AEAD Encrypted Data Packet qui est complètement différent de celui actuellement utilisé par OpenPGP.js (puisque les développeurs d’OpenPGP.js se sont basés sur des travaux préliminaires), alors qu’ils utilisent le même code. À la sortie du RFC 4880bis, l’implémentation d’OpenPGP.js va donc devoir être mise à jour pour se conformer à la version finale du standard (c’est déjà noté par les développeurs)… et de fait casser la compatibilité avec leur implémentation actuelle !

Les nouveautés d’OpenPGP.js 3.0.4

Les notes de version fournissent un descriptif complet, retenons tout de même les points suivants.

Prise en charge des courbes elliptiques

La plus importante est la prise en charge de la cryptographie à base de courbes elliptiques (ECC, Elliptic Curve Cryptography). Concrètement, il est désormais possible de générer et utiliser des clefs publiques ECDSA (pour la signature) et ECDH (pour le chiffrement). L’avantage est une réduction significative de la taille des clefs, par rapports aux clefs RSA, DSA ou ElGamal. Les courbes prises en charge sont celles du NIST, les courbes Brainpool, et la courbe 25519.

Attention à l’interopérabilité si vous utilisez de telles clefs. D’une part, pour l’instant, seules les courbes du NIST font officiellement partie du standard OpenPGP (depuis le RFC 6637), les autres courbes sont ajoutées par le RFC 4880bis, qui n’est encore qu’un brouillon (cela dit, il y a peu de chances que les identifiants associés à ces courbes changent d’ici la version finale). D’autre part, GnuPG ne prend en charge la cryptographie elliptique que depuis sa version 2.1, certes sortie il y a maintenant plus de trois ans, mais les versions 1.x et 2.0.x font encore de la résistance.

Masquage de l’identité du destinataire

L’autre nouveauté — beaucoup plus anecdotique — se cache derrière le nom wildcard key ID et consiste en la possibilité de masquer l’identité du destinataire d’un message chiffré. C’est en fait l’équivalent des options --throw-keyids ou --hidden-recipient de GnuPG.

Comme évoqué plus haut, sous sa forme la plus simple un message chiffré se présente sous la forme de deux paquets : un premier paquet contenant une clef de session chiffrée avec la clef publique du destinataire, suivi d’un paquet contenant le corps du message chiffré avec la clef de session. Dans le premier paquet, on trouve normalement l’identifiant de la clef publique du destinataire, ce qui permet au logiciel du destinataire de savoir immédiatement quelle clef utiliser pour déchiffrer la clef de session. Mais cela a aussi pour effet de révéler indirectement l’identité dudit destinataire (il suffit de savoir à qui appartient la clef référencée).

Utiliser une wildcard key ID consiste à ne pas inclure l’identifiant de la clef du destinataire dans le premier paquet (ou, plus précisément, à inclure un identifiant factice composé uniquement de zéros). À la réception d’un tel message, le logiciel du destinataire va simplement essayer successivement toutes les clefs privées à sa disposition, jusqu’à trouver celle qui permet de déchiffrer la clef de session. Ce n’est pas supposé prendre beaucoup de temps, dans la mesure où un utilisateur n’a typiquement qu’une seule clef de chiffrement de toute façon (plus, éventuellement, quelques anciennes clefs arrivées à expiration qu’il garde pour déchiffrer des vieux messages).

Attention toutefois, dans le cadre du courrier électronique, utiliser une wildcard key ID ne change rien au fait qu’OpenPGP ne protège que le corps du message et que toutes les métadonnées du courrier électronique (dont l’en‐tête To: et la commande SMTP RCPT TO) sont toujours en clair (sauf à utiliser TLS). Le gain en confidentialité apporté par cette fonctionnalité est donc très relatif.

Les changements sous le capot

Au‐delà des nouvelles fonctionnalités, OpenPGP.js a fait l’objet d’un réusinage assez conséquent pour cette version 3.0.0. Notamment, plusieurs des bibliothèques sur lesquelles s’appuient OpenPGP.js ont changé :

Le code JavaScript utilise désormais ECMAScript 6 pour la déclaration des variables et ECMAScript 7 pour le code asynchrone. La compatibilité avec les anciens navigateurs étant maintenue grâce à Babel. Par ailleurs, la cohérence du style du code est maintenant vérifiée avec ESLint.


  1. Robert J. Hansen: « Removing [SHA-1] cuts down on the amount of (wholly inappropriate) fearmongering that gets thrown aroung by the ignorant whenever SHA-1 is mentioned. OpenPGP adoption is slow enough already; continued use of SHA-1, even where it’s safe, seems contraindicated. » 

  • # chiffrer l' objet

    Posté par . Évalué à 5.

    "OpenPGP ne protège que le corps du message"
    Il semblerait qu'Enigmail ai trouvé un mécanisme bien pratique pour contourner ceci et chiffrer l'objet, en le remplaçant par quelque chose comme "Encrypted Message".
    cf https://www.enigmail.net/index.php/en/user-manual/handbook-faq#How_can_I_encrypt_the_Subject.3F

    cela serait dû non à GnuPG, mais à un standard en cours de développement, le "Memory Hole Standard".

    cf https://www.enigmail.net/index.php/en/user-manual/advanced-operations section extensions.enigmail.protectHeaders

    • [^] # Re: chiffrer l' objet

      Posté par (page perso) . Évalué à 9.

      cela serait dû non à GnuPG, mais à un standard en cours de développement, le "Memory Hole Standard".

      « En cours de développement » ? Avec un nom de domaine qui ne mène plus nulle part (pas d’enregistrements A ou AAAA), un dépôt sur GitHub plus mis à jour depuis trois ans, qui renvoie à un autre dépôt à peine plus actif dans lequel le brouillon de standard n’a plus été modifié depuis 2015 alors qu’il ne spécifie encore rien du tout ?

      Jusqu’à preuve du contraire, ce n’est pas « en cours de développement », c’est « abandonné » pour ne pas dire « mort-né ».

      L’auteur admet d’ailleurs que compléter ce brouillon n’est plus sa priorité, même s’il ne va pas jusqu’à dire qu’il est formellement abandonné.

      • [^] # Re: chiffrer l' objet

        Posté par (page perso) . Évalué à 6.

        L’auteur admet d’ailleurs que compléter ce brouillon n’est plus sa priorité

        Pour ne pas être injuste : l’auteur en question, Daniel Kahn Gillmor (dkg), est un développeur Debian (en charge, entre autres, des paquets relatifs à GnuPG), contributeur à GnuPG, activiste de l’ACLU, et membre actif de l’IETF dans le domaine de la sécurité (notamment très impliqué dans le travail en cours sur le RFC 4880bis). Pour ne parler que des casquettes que je lui connais.

        On peut comprendre qu’il ait d’autres priorités. :)

        • [^] # Re: chiffrer l' objet

          Posté par . Évalué à 1.

          La norme n'est peut-être plus en développement, mais l'implémentation du chiffrage de l'objet semble par contre bien en place.

          • [^] # Re: chiffrer l' objet

            Posté par (page perso) . Évalué à 3.

            Sans spécification correspondante et donc sans garantie que cela soit compris par d’autres implémentations qu’Enigmail, l’intérêt est réduit. La raison d’être d’OpenPGP est de garantir l’interopérabilité (sinon on aurait pu continuer à utiliser PGP pour n’échanger qu’avec des utilisateurs de PGP, sans se soucier de ceux qui utilisent autre chose).

            • [^] # Re: chiffrer l' objet

              Posté par (page perso) . Évalué à 5.

              Sauf qu'à ma connaissance, ça n'impacte pas trop la compatibilité, ça va juste rendre le sujet du mail message inutile. Du coup, ce n'est pas forcément un mal. Le sujet est toujours masqué et peut être déchiffrés par ceux qui utilisent enigmail. C'est une fuite d'information en moins.

              C'est sûr que ça n'est pas l'idéal.

              « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

          • [^] # Re: chiffrer l' objet - On dit chiffrement pas chiffrage

            Posté par . Évalué à 2.

  • # Surface d'attaque OpenPGP.js & GnuPG

    Posté par . Évalué à 9.

    J'ai rédigé le morceau sur la surface d'attaque, et j'aimerais apporter une nuance / digression.

    En tant que programme compilé, GnuPG a bien une surface d'attaque réduite comparé à OpenPGP.js. En revanche, si l'on utilise GnuPG à travers le plugin enigmail et donc thunderbird, alors on augmente significativement la surface d'attaque, en atteste un récent audit de sécurité: https://posteo.de/en/blog/security-warning-for-thunderbird-users-and-enigmail-users-vulnerabilities-threaten-confidentiality-of-communication

    La surface d'attaque de GnuPG reste faible, c'est l'environnement d'appel (Enigmail + Thunderbird) qui réduit le niveau de sécurité. De manière analogue, la librairie OpenPGP.js peut être parfaitement codée, lorsqu'on l'utilise dans un navigateur, on augmente significativement la surface d'attaque.

    My 2 cents.

    • [^] # Re: Surface d'attaque OpenPGP.js & GnuPG

      Posté par . Évalué à 2.

      A propos de cette vulnérabilité d'Enigmail, je vois qu'il est conseillé de le désinstaller parce que la sécurité de nos données pourrait-être compromise. Mais si on le vire on ne peut plus chiffrer les messages et les données sont encore plus compromises, non?

      • [^] # Re: Surface d'attaque OpenPGP.js & GnuPG

        Posté par (page perso) . Évalué à 2.

        Pour éviter les failles de sécurité, évitez la sécurité… pour une meilleure réponse sur le sujet, voir les différents commentaires de gouttegd, dont

        https://linuxfr.org/nodes/114463/comments/1738994

      • [^] # Re: Surface d'attaque OpenPGP.js & GnuPG

        Posté par . Évalué à 3.

        La recommandation dans l'audit pour Thunderbird: Mettre a jour et désactiver toutes les extensions. Ne pas utiliser de flux RSS dans Thunderbird.

        Pour Enigmail: Mettre a jour vers 1.9.9 et n'utiliser que l'extension Enigmail.

        Ce sont des failles spécifiques a thunderbird qui sont différentes de celles récemment commentées. Ci-dessous la version originale.

        For all Thunderbird users:

        • Update Thunderbird to the latest versions as soon as they are available. The new versions will remove several of the vulnerabilities that were revealed in this audit.
        • Use Thunderbird preferably without or at least with verified add-ons until the architecture of Thunderbird has been rebuilt.
        • Do not use RSS feeds in Thunderbird for now. There are critical security problems threatening your entire communication.
        • Do not accidentally install add-ons through phishing, since rogue add-ons can be used to attack you.

        If you follow these security recommendations, your communication will be notedly more secure.

        For Enigmail users:

        • Update Enigmail immediately to the new version 1.9.9. This update removes all vulnerabilities identified in this audit.
        • Update Thunderbird to the latest versions as soon as they are available. The new versions will remove several of the vulnerabilities that were revealed in this audit.
        • Do not install any other add-on except for Enigmail until the add-on architecture of Thunderbird has been rebuilt.
        • Do not use RSS feeds in Thunderbird for now. There are critical security problems threatening your entire communication.
        • Do not accidentally install add-ons through phishing, since rogue add-ons can be used to attack you.

        If you follow these security recommendations, your communication is notedly more secure.

  • # Doublon

    Posté par (page perso) . Évalué à 3.

    Sept contributeurs (dont moi) ont travaillé sur cette dépêche, un modérateur l’a validée, et on a quand même trouvé le moyen de ne pas voir que le titre de la première section (« OpenPGP ») était en doublon… Doh! :D

    Sorry about that. Si un modérateur pouvait retirer le « OpenPGP » surnuméraire, merci.

    • [^] # Re: Doublon

      Posté par (page perso) . Évalué à 5.

      Corrigé, merci. En fait ça venait d'une correction post-modération (n° de révision 262 du 16 avril 2018 21:53:04).

  • # ProtonMail

    Posté par . Évalué à 5.

    Merci pour cette dépêche très riche et intéressante.

    En lisant la partie sur OpenPGP.js, je découvre que des développeurs de ProtonMail travaillent sur ce code. C'est à mon avis une très bonne nouvelle car c'est une preuve concrète de l'implication de ProtonMail dans du code libre après quelques débuts hésitants (le journal et les commentaires associés étaient méfiants sur le sujet du libre).

    • [^] # Re: ProtonMail

      Posté par (page perso) . Évalué à 10. Dernière modification le 19/04/18 à 01:26.

      C'est à mon avis une très bonne nouvelle car c'est une preuve concrète de l'implication de ProtonMail dans du code libre

      Oui, alors à choisir je préférerai qu’il fasse du code non libre et interopérable plutôt que du code libre intentionnellement conçu pour ne pas pas être interopérable.

      ProtonMail prend bien soin de mettre en avant le fait qu’ils ont choisi d’utiliser un protocole standard (OpenPGP). Par exemple :

      We believe in compatibility and interoperability. Thus, ProtonMail’s encryption complies fully with the OpenPGP standard. This brings a number of benefits. Because we are using an open standard, you as the user can know exactly how we are applying end-to-end encryption to secure your emails. In the future, we will be adding to ProtonMail the ability to import and export PGP keys. By complying with OpenPGP, it will be possible to do things like, download ProtonMail messages and decrypt them locally using your own PGP software.

      Ou encore :

      Why does ProtonMail use the OpenPGP standard? The reason is interoperability. By adhering to OpenPGP, we enable not just end-to-end encrypted messaging with other ProtonMail users, but compatibility with any PGP user worldwide. This means anybody, regardless of what email provider they use, can send end-to-end encrypted messages to ProtonMail users.

      C’est beau comme de l’antique, pas vrai ?

      Sauf que c’est du pipeau. Dans les faits, le chiffrement proposé par ProtonMail n’est utilisable qu’entre utilisateurs de ProtonMail.

      Vous voulez envoyer un mail chiffré à un correspondant qui n’utilise pas ProtonMail ? Pas moyen. Les seules clefs publiques que vous pouvez utiliser depuis ProtonMail sont celles des autres utilisateurs de ProtonMail. Il est impossible d’importer une clef publique tierce pour l’utiliser depuis ProtonMail. Ça fait trois ans que la fonctionnalité est promise (notez par exemple la phrase commençant par In the future dans la citation ci-dessus), les utilisateurs l’attendent toujours.

      La seule option pour envoyer un mail chiffré à un non-utilisateur de ProtonMail est d’utiliser leur méthode complètement non-standard qui consiste en gros à chiffrer le message symmétriquement avec un mot de passe et à envoyer votre correspondant sur une page web où il pourra entrer le mot de passe en question pour lire le message (et c’est à vous de vous débrouiller pour communiquer le mot de passe à votre correspondant).

      Si vous voulez pouvoir recevoir sur ProtonMail des messages chiffrés provenant de correspondants non-ProtonMail, c’est théoriquement possible. Vous pouvez exporter votre clef publique, la diffuser comme bon vous semble, et donc la faire parvenir à vos correspondants qui peuvent dès lors l’utiliser pour chiffrer les messages qui vous sont destinés… Sauf que la possibilité d’exporter la clef publique semble avoir disparu des versions récentes de ProtonMail, et depuis ProtonMail ne cesse de promettre que ça va revenir « dans une version future ».

      Concrètement, les seules personnes chez ProtonMail qui se soucient d’interopérabilité sont dans le département marketing, où « interopérabilité » est comme « open source » : c’est un mot qu’il est bon de caser partout où on peut sur le site web. Dans les faits, OpenPGP ou pas, ProtonMail ne propose de chiffrement de bout en bout qu’entre ses propres utilisateurs.

      À part ça, oui, ProtonMail contribue à un projet open source. C’est bien mais ça n’en reste pas moins un service qui chercher à enfermer ses utilisateurs tout en se vantant d’être interopérable (non).

      • [^] # Re: ProtonMail

        Posté par (page perso) . Évalué à 10.

        Précision : la bibliothèque OpenPGP.js n’a rien à voir avec le fait que ProtonMail ne permet le chiffrement qu’entre ses utilisateurs. Que ProtonMail ne soit pas interopérable avec l’extérieur est purement un choix de ProtonMail, qui n’est pas lié à une hypothétique limitation d’OpenPGP.js.

        OpenPGP.js est une implémentation complète et conforme du standard OpenPGP, parfaitement capable d’interopérer avec une autre implémentation conforme (sauf si l’option aead_protect est activée, comme expliqué dans la dépêche).

  • # Pourquoi pas GCM ?

    Posté par . Évalué à 2.

    Merci pour cette dépêche avec tous ces détails, c'est toujours intéressant à lire!

    J'ai une question par rapport au choix des modes AEAD : pour ne pas avoir retenu GCM ? Sur la page de Wikipédia de GCM il est écrit qu'il n'y a pas de problèmes de brevets et quelques bémols au niveau sécurité sont mentionnés mais rien qui n'ait l'air catastrophique (bien que ça dépasse mon niveau de compréhension en cryptographie).

    D'ailleurs il me semble que son utilisation est pas mal répandue à travers TLS (sur LinuxFR par exemple mon Firefox utilise AES_128_GCM).

    • [^] # Re: Pourquoi pas GCM ?

      Posté par (page perso) . Évalué à 6.

      pourquoi ne pas avoir retenu GCM ?

      GCM ne fait pas l’unanimité chez les cryptographes. Ou alors, il fait l’unanimité contre lui.

      D’après Jon Callas (un des membres du groupe de travail OpenPGP, et premier auteur du RFC 4880) :

      I’ll request that another mode than GCM be used. In particular, I disagree with it being "uncontroversial." It's the most controversial mode you could pick.

      GCM is very brittle. It breaks in very bad ways if you aren't careful with nonces/tags. There are many cases of people misusing it and getting worse than no security. I state that because if you think you're getting authenticated data, but it's actually been altered in transit, and that will likely cause issues in the receiving state machine.

      Ou d’après Matthew Green :

      Galois Counter Mode has quietly become the most popular AE(AD) mode in the field today, despite the fact that everyone hates it. The popularity is due in part to the fact that GCM is extremely fast, but mostly it’s because the mode is patent-free. […]

      Une chose qui revient souvent dans la littérature sur GCM est sa fragilité (cf. le commentaire de Jon Callas, GCM is very brittle) dans le sens où il est très facile de l’utiliser de façon catastrophique. Voir par exemple Gueron and Krasnov (2013), Joux (2006), Ferguson (2005).

      Au contraire, OCB est encensé par tout le monde, comme Brian Carlson (OCB is the mode everyone really wants to use), Jon Callas (We all really want to use OCB) ou Matthew Green (OCM blows the pants off of all the other modes I mention in this post)… la seule critique à son égard étant ce censuré de brevet. D’ailleurs comme le dit Werner Koch :

      GCM has only be developed to avoid the OCB patent

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.