OpenSSL et la cryptographie

La mise en place du chiffrement/déchiffrement dans sylabe, l’implémentation de nebule en php, révèle quelques problèmes et spécificités de OpenSSL.

Lorsque il a fallu déchiffrer avec la commande openssl les objets chiffrés depuis sylabe, ça n’a pas marché.

Les objets chiffrés par sylabe, qui utilise openssl dans php, peuvent être déchiffrés par sylabe. Les objets chiffrés par nebule en bash, qui utilise la commande openssl, peuvent être déchiffrés via la même commande en bash. Le point commun est l’utilisation de la librairie openssl. Mais en pratique un objet chiffré dans sylabe que l’on essaye de déchiffrer avec la commande openssl (via nebule en bash) retourne une erreur ‘Bad Magic Number’. Et l’inverse ne marche pas non plus. Ah, c’est moche…

Salage

Le problème ici est lié à l’utilisation d’un ‘salage’ (salt). Cette valeur est générée aléatoirement par openssl pour complexifier le mot de passe de chiffrement et réduire les attaques par dictionnaire de mots de passe pré-hashés (rainbow-table). Le sel est une valeur publique contrairement au mot de passe, et doit impérativement être envoyé avec le fichier chiffré. Le salage est un renforcement de la procédure de chiffrement et non du mot de passe lui-même. Pour que le sel soit transmit avec les données chiffrées, openssl ajoute un petit entête aux données chiffrées avec notamment la valeur du sel. Il en résulte une petite augmentation de la taille du fichier des données chiffrées de 16octets. Or, la librairie openssl utilisée dans php ne génère pas de sel, les données chiffrées et non chiffrées ont la même taille.

Quelle solution apporter ?

Il est possible de gérer cet entête de fichiers chiffrés dans le code php. Cela entraîne une augmentation de la complexité du chiffrement/déchiffrement mais permet de conserver un comportement commun avec les objets actuellement générés en bash. Cette compatibilité ‘commune’ n’est pas universelle puisqu’elle n’est pas gérée par la librairie openssl dans php, et donc peut-être pas non plus dans d’autres environnements.
On peut aussi ne pas permettre d’utiliser un entête particulier et de gérer le salage de la même façon que l’IV. Cette solution casse la gestion des objets chiffrés actuels mais surtout complexifie les liens de chiffrement.
Une autre solution serait de ne pas utiliser le salage du tout. Une option de openssl le permet : -nosalt. Cela permet d’avoir un chiffrement plus simple et des objets chiffrés plus propres, et donc une implémentation plus universelle du chiffrement. On va cependant à l’encontre des recommandations faites par les développeurs de OpenSSL. Et on ré-ouvre potentiellement par dictionnaire pré-calculés.

Mais a-t-on vraiment besoin du salage ?

Le salage permet en fait de renforcer la sécurité de mots de passes potentiellement faibles ou à la limite de l’attaque par force brute.
Le chiffrement des objets dans nebule impose l’utilisation d’une clé de session aléatoire. Si l’espace des valeurs des clés de sessions est aléatoire et suffisamment grand, une attaque par dictionnaire est impossible. C’est impossible parce qu’il est dans ce cas précis impossible de pré-calculer et encore moins de stocker dans un dictionnaire l’intégralité des valeurs possibles. Un espace des valeurs de clé suffisamment grand peut se comprendre par une entropie correspondant à 128bits et plus.

Le script bash référence de nebule génère actuellement une clé de session de 64octets de valeurs hexadécimales, soit 256bits d’entropie réelle. Le code php de sylabe génère actuellement une clé de session de 128octets aléatoires, soit 1024bits d’entropie réelle.

Donc, le salage va être volontairement supprimé dans le chiffrement des objets tel que mis en place dans nebule.

Semence

Un problème similaire existe avec l’IV (Initial Vector, vecteur initial ou semence).

Lorsque l’on réalise un chiffrement symétrique, celui-ci se fait typiquement par blocs de données. Ce découpage peut entrer en interférence, en quelque sorte, avec les données à chiffrer. Si ces données sont répétitives suivant la taille du bloc ou un multiple, alors les blocs de données chiffrées correspondantes vont être identiques. Et cette répétition est détectable et fourni des informations sur le contenu non chiffré…
Pour remédier à ce problème, il existe différentes méthode d’organisation du chiffrement (pour le même algorithme de chiffrement) que l’on appelle modes d’opération. Certains modes introduisent un chaînage entre des blocs contiguës pour camoufler les données répétitives. D’autres modes mettent en place d’un compteur par bloc qui sera combiné avec les données pour forcer un peu de variabilité entres blocs répétitifs.
Il reste cependant à traiter le premier bloc. Pour cela on utilise l’IV qui est soit la première valeur pour le chaînage soit la première valeur du compteur en fonction du mode d’opération. Parce que sinon ce premier bloc, chiffré avec le même mot de passe, donnera le même bloc chiffré et donc trahira un début de données identique entre plusieurs fichiers chiffrés. L’IV est une valeur publique contrairement au mot de passe, et doit impérativement être envoyé avec le fichier chiffré.

Mais a-t-on vraiment besoin de cet IV ?

Comme dans le cas du salage, l’utilisation de d’une clé de session aléatoire et différente pour chaque objet fait que, même pour un contenu identique dans les premiers blocs, cela donnera des blocs chiffrés différents.

Donc, le vecteur initial va être volontairement supprimé dans le chiffrement des objets tel que mis en place dans nebule.

Premier problème suite à ça, l’instruction en php openssl_encrypt nécessite un paramètre IV non nul…

Renouveler son entité

Pour l’instant, les entités sont figées. Mais il faudra prévoir de changer leurs mots de passes et de les migrer vers de nouvelles entités au besoin.

Le changement de mot de passe nécessite de régénérer l’objet de clé privé qui change. Il faut évidemment préalablement déverrouiller l’entité, donc sa clé privée. Une fois le mot de passe changé, il faut lier la nouvelle clé privée à la clé publique puis supprimer le lien de l’ancienne clé privé. Il faut marquer à supprimer l’objet de l’ancienne clé privée.

Dans le cas d’une migration d’entité, c’est un peu plus complexe. Ce besoin répondra souvent suite à un problème de compromission ou de corruption d’entité.
Il faut générer une nouvelle entité autonome. Faire un lien de mise à jour de l’ancienne entité vers la nouvelle. Dans la mesure du possible, ce lien de mise à jour doit être signé à la fois par l’ancienne et la nouvelle entité. Puis l’objet de la clé privée de l’ancienne entité doit être marqué à supprimer à la fois par l’ancienne et la nouvelle entité.
Si l’entité avait été corrompue, c’est à dire qu’il était impossible de la déverrouiller, c’est un vrai problème. Dans ce cas, les liens de mise à jour d’entité et de suppression de clé privée ne pourront être signés par l’ancienne entité. rien ne permet de distinguer une opération légitime suite à un problème d’une tentative de détournement par une autre entité. Il peut tout au plus être possible de regarder si l’entité génère de l’activité, donc qu’elle n’est pas corrompue.
En cas de compromission de l’entité, on peut faire une mise à jour vers une nouvelle entité. Mais celui qui a volé la clé privée de l’entité peut le faire aussi de son côté. Il est difficile dans ce cas de déterminer qui est la véritable nouvelle identité et pas une usurpation… Peut-être le côté sociale, comportemental, d’une entité peut nous aider à posteriori?

Vote électronique

Ceci est une réflexion personnelle, mais comme elle concerne le traitement sécurisé de certaines données, je pense qu’elle a aussi sa place sur le blog nebule.

Le vote électronique, vu par un non spécialiste, est un monde assez étrange. D’un côté une grande variété de sociétés commerciales qui disent toutes avoir trouvé le système parfait, et j’image un minimum rentable. De l’autre côté une variété tout aussi diverse de personnalités du monde de la sécurité informatique (peut-être un peu usurpée pour certaines) qui s’évertuent à démonter les fameuses solutions miracles et commerciales. Démonter est à prendre dans le sens commun, mais aussi dans le sens péjoratif.

En y regardant de plus près, on découvre que certaines réflexions ont déjà été menées, par exemple par la Commission Nationale de l’Informatique et des Libertés (CNIL). On trouve notamment la Délibération n° 2010-371 du 21 octobre 2010 portant adoption d’une recommandation relative à la sécurité des systèmes de vote électronique. Mais on trouve aussi des avertissements sur les produits de certaines sociétés.

On peut regarder un résumé de délibération de 2010 comparée à celle de 2003. On y parle toujours de sécurité du système hôte et de son (ses) logiciel(s) et de scellement. Ce scellement est finalement quelque chose que l’on pourrait assez facilement mettre en place avec un système comme nebule, c’est nativement sa façon de fonctionner…

Mais on accepte aussi désormais de faire de la virtualisation sur le système centrale !?
Pardon?
Cela veut dire de fait la nécessité de certifier aussi l’intégralité de la plate-forme de virtualisation au même niveau que les serveurs dédiés aux votes. Pourquoi vouloir complexifier la chose alors qu’il est nécessaire au contraire de simplifier l’ensemble du système si on veut espérer pouvoir le certifier. Autant mettre le serveur dans les nuages (le cloud) tant qu’on y est…

Mais quelles sont les exigences d’un vote?
On parle ici de confidentialité du vote. Ici de reproductibilité, traçabilité et intégrité. Ici d’impossibilité de vérification de la machine. Etc…
Le code électoral est de son côté une mise en application mais ne décrit pas les fondements, les principes.

Bref, bon courage pour ceux qui voudraient essayer de comprendre quelque chose au débat et démêler les intérêts de chacun…

Je propose de repartir du début. Que représente le vote pour moi ?

  1. Je veux être capable à tout instant de pouvoir vérifier que mon vote, c’est à dire mon choix, est pris en compte et n’est pas modifié ou oublié.
  2. Je veux être capable de vérifier à tout instant les voix recueillies par chaque candidats. Je dois pour cela avoir accès à l’intégralité des votes et voir que chaque votant est unique.
  3. Ce que je demande, tout citoyen doit pouvoir lui aussi le demander. Cela veut dire aussi que mon voisin doit être capable de vérifier mon vote, et vice versa.

Certaines règles sont optionnelles :

  1. Les citoyens sont pré-enregistrés par une autorité, c’est à dire une entité de confiance. L’autorité de confiance peut ou non être lié au précédent élu. Les citoyens sont généralement les personnes référencées par le gouvernement d’un pays.
  2. La manière de calculer le candidat vainqueur est déterminée à l’avance. C’est normalement celui qui remporte le plus de voix. Ce peut être aussi avec un pourcentage minimum.

Pour résoudre toutes ces demandes :

  1. Il faut que chaque partie en présence, électeurs et candidats, soit identifiés.
  2. Il faut matérialiser le vote, c’est à dire le lien entre l’électeur et le candidat.

L’identification peut être faible (papier) ou forte (signature cryptographique). Dans le cas du vote papier, le votant prouve son identité avec sa pièce d’identité. Un registre empêche le rejeu du vote. Un unique papier permet de matérialiser le vote pour un candidat. Si l’ensemble de la chaîne de vote est solide, cela revient à faire un lien entre un votant unique et un candidat unique. Avec nebule, il suffit de ne prendre que le dernier lien vers les candidats, ainsi un seul vote est possible.

Comment peut-on gérer un anonymat du vote?
Le lien direct et public entre votant et candidat ne permet pas de maintenir l’anonymat. Pourtant celui-ci est nécessaire mais pas obligatoire. Un votant peut très bien décider de rendre public son vote. C’est dans ce cas au votant de casser l’anonymat de son vote.
On peut donc accepter une entité anonyme, dépendante de notre vraie entité, pour voter. Il faut prévoir le mécanisme qui permet à une autorité de reconnaître cette entité dépendante comme étant l’entité qui a le droit de vote, et elle seule. Ce mécanisme doit inclure des liens secrets entre les entités maîtres et les entités votant réellement.

A gratter…

Chiffrement et subdivision

Le chiffrement permet offusquer des données, c’est à dire de protéger celle-ci d’une diffusion inappropriée.

La subdivision consiste, à partir d’un objet unique, en la création de plusieurs objet dérivés plus petits. Ces petits objets sont des sous-ensembles de l’objet principal, c’est à dire des morceaux. Ce n’est pas encore implémenté aujourd’hui, mais le type de lien existe pour définir la relation de morcelage entre l’objet principal et les sous-objets.
La subdivision permet de découper un objet en bloc pour qu’il puisse être transmis par morceaux à la manière du P2P.
La subdivision peut aussi et simultanément être utilisée afin de constituer un index de certaines portions intéressantes. Cela peut être par exemple un index des mots dans un texte pour permettre une recherche accélérée sur des mots clés.

Cependant, la combinaison du chiffrement et de la subdivision pose un problème de confidentialité.

Que se passe-t-il si on décide de protéger un objet contenant du texte, c’est à dire le chiffrer, mais que l’on ne retire pas les liens de subdivision ?
Si ces liens de subdivision renvoient vers des parties d’un index des mots clés, alors il est possible de reconstituer les grandes idées du texte. Voir il est possible de reconstituer dans le pire des cas l’intégralité du texte déchiffré. On contourne ainsi la protection mise en place.

Il faut cependant noter que si un objet est protégé à posteriori, il a peut-être déjà été copié légitimement. Il pourrait en être de même de certaines parties marquées comme subdivisions.

Afin de minimiser ce problème de confidentialité, il y a plusieurs règles à appliquer :

  1. Ne jamais faire de liens de subdivision sur un objet protégé mais uniquement sur son dérivé chiffré.
  2. Si une protection est activée pour un objet existant, supprimer tous les liens de subdivision.
  3. Si l’objet est nouveau et doit être protégé, ne pas faire de liens de subdivision sur celui-ci mais uniquement sur son dérivé chiffré.

Lorsqu’il sera possible d’offusquer des liens, ces règles pourront être revues.