Comment fonctionne apicrypt

Introduction

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)
...

Algorithme de chiffrage

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

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;
Clé de cryptage apicrypt simulée.

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.

Programmes de chiffrement et génération de clés

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)

Failles potentielles du système apicrypt

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.

Conclusion

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.

Liens intéressants