Le système apicrypt est un système permettant d'échanger des données médicales de façon confidentielle entre les professionnels de santé. Le Site officiel du système apicrypt indique que le chiffrement est de type masque jetable (one time pad) mais reste très succinct sur l'algorithme utilisé.
Heureusement, on peut trouver des executables en lignes de commande pour linux permettant de crypter et décrypter des messages avec le système apicrypt. On peut s'intéresser particulièrement au programme nommé apicrypt
dont l'exécution affiche :
Apicrypt : cryptage de documents texte pour transit en corps d'email (c)2005 APICEM v1.0 usage : apicrypt -s fichiersource -o fichierarrivee -u utilisateur [-k cheminclefs] -d destinataires
Il est intéressant de noter que ce fichier contient encore un certain nombre de symboles de débogage, ce qui aide beaucoup pour comprendre le fonctionnement du programme. En exécutant la commande objdump -C -t apicrypt
on obtient entre autre :
apicrypt: format de fichier elf32-i386 SYMBOL TABLE: ... 0804efa4 g F .text 000000b6 TypCrypto::Crypt(unsigned char *, unsigned long, unsigned char **, unsigned long *, TypFileRef *) 08048e70 g F .text 0000002d crypter(char *, char *, char *, char *, char *) 0804f0e4 g F .text 000001de TypCrypto::UnCrypt(unsigned char *, unsigned long, unsigned char **, unsigned long *) 0804f2c4 g F .text 000002e7 TypCrypto::GetLinearKey(unsigned char *, unsigned long, TypFileRef *, unsigned long, long) ...
L'analyse du programme apicrypt
montre que l'algorithme utilisé est un chiffrement de flux. Le message d'origine subit successivement les opérations suivantes :
Après ces deux opérations, le message binaire est converti en caractères imprimables ASCII à l'aide d'un codage de types base64 légèrement modifié et utilisant un alphabet non standard.
Le message est alors envoyé au serveur apicrypt qui déchiffre le message à l'aide de la clé personnelle de l'émetteur, le chiffre avec la clé personnelle du destinataire et transmet le message au destinataire.
Lors d'une étape de chiffrage avec la clé maître ou la clé personnelle, le programme ajoute au message l'entête de la clé utilisée. Cet entête contient les informations nécessaires au destinataire du message (ou au serveur apicrypt) pour déterminer la clé à utiliser pour déchiffrer le message .
Les clés de cryptage sont distribuées aux utilisateurs d'apicrypt au début de chaque année. Ils reçoivent un cdrom contenant les fichiers de clé qu'ils doivent installer pour pouvoir continuer à utiliser le système.
Un fichier de clé (maître ou personnelle) est composé d'un entête qui a la structure suivante :
typedef struct{ u_int32_t version; // Version d'apicrypt u_int32_t annee; // Année de la clé u_int32_t nombre2; // taille de la chaîne qui suit u_int8_t data2[32]; // "1000" ? u_int32_t utilStrSize; // taille de la chaîne du nom d'utilisateur u_int8_t utilStr[40]; // nom d'utilisateur u_int32_t indexMax; // taille de la clé u_int32_t indexCourant; // décalage courant dans cette clé u_int32_t nbCrypt; // nombre de messages cryptés u_int8_t data3[124]; // aucune idée... } KeyHeaderStruct;
Les données contenues dans data3
ne semblent pas être utilisé lors du chiffrement du message et ne sont pas nécessaires à leur déchiffrement.
L'entête est suivi d'une suite d'octets aléatoires qui sont utilisés pour former les clés successives. La taille des fichiers de clé est de l'ordre d'une vingtaine de Mo.
Pour vérifier le système de chiffrement du système apicrypt, j'ai créé un programme qui permet de crypter un message texte et un autre qui permet de créer des clés de cryptage. Les messages cryptés avec ce programme sont correctement décryptés par l'exécutable officiel apiuncrypt
disponible ici. Les codes sources de ces deux programmes sont disponibles sur github
Attention ! Il ne faut pas utiliser ces programmes tels quels pour chiffrer et envoyer des messages apicrypt réels, ils ne sont pas sûrs et utilisent systématiquement la même clé de cryptage pour tous les message ce qui présente un gros risque pour la confidentialité des messages envoyés. (voir partie suivante)
Le chiffrement par masque jetable offre une sécurité théoriquement absolue si les trois conditions suivantes sont scrupuleusement respectées :
Pour vérifier que les clés fournies par apicrypt sont parfaitement aléatoires il faudrait en faire une analyse statistique précise ou connaître la méthode utilisée pour les générer.
On a vu que les clés de cryptage sont fournies chaque années et ont une taille d'environ une dizaine de Mo. Cela impose que, pour assurer une confidentialité totale, la taille des messages envoyés ne doit pas dépasser quelques dizaines de Mo. En pratique cela n'est pas très contraignant tant que les messages sont des textes et ne comportent pas de pièces jointes.
Le dernier point est le plus problématique. En effet, chaque message émis (ou reçu) use progressivement les clés reçues en début d'année. En analysant l'exécutable de chiffrement, on remarque que lorsqu'une des clés est complètement épuisée, elle est remise à zéro et à nouveau utilisée à partir du début. Cela a pour conséquence que si la taille totale des messages reçus ou émis pendant une année dépasse la taille de la clé (une vingtaine de Mo), une même clé sera utilisée pour chiffrer deux messages différents, ce qui en compromet la confidentialité
Pour ne rien arranger, les connexions au serveur apicrypt se fasse par les protocoles pop3 et smtp non chiffrés, ce qui signifie que les données (cryptées par apicrypt) circulent en clair.
Quelques commentaires intéressants sont à lire à ce sujet sur reddit ici et ici. Ils laissent imaginer une attaque possible contre le système. Un individu A crypte ses emails pour éviter qu'un individu B qui intercepte ses communications puisse en connaître le contenu. Vu le fonctionnement d'apicrypt, l'individu B s'il possède un compte apicrypt peut envoyer à A un message chiffré d'une longueur supérieure à celle de la clé de A. Si B intercepte à l'arrivée chez A le message chiffré avec la clé de A, connaissant le message en clair, il peut déterminer la totalité de la clé de A ! Le fait que le message soit aussi chiffré par la clé maître ne change rien car B possède la même clé maître que A.
Il semble que le système de chiffrement utilisé par apicrypt présente un certain nombre de failles. Mais n'étant pas (loin de là) un spécialiste en cryptographie, je laisse les gens plus compétents en juger.
Il faut aussi noter que le serveur d'apicrypt a accès à tous les messages échangés en clair, ce qui n'est pas forcément souhaitable loin de là. Notamment la confidentialité de l'ensemble des messages échangés dépend de la sécurité de ce serveur.
On peut néanmoins regretter que les algorithmes utilisés par apicrypt ne soient pas publiques, et plutôt que de déposer le code source des algorithmes de cryptage chez un notaire (point 6), il serait plus sûr de les déposer dans le domaine public.