Renforcement de la lecture des objets – taille limite

Suite de l’article sur le Renforcement de la lecture des objets, type hash invalide et affichage.

Le renforcement de la lecture des objets et notamment la suppression sur empreinte invalide ou invérifiable entraîne un autre effet. Tout objet plus grand que la taille limite de lecture des contenus des objets, définit par l’option ioReadMaxData, est automatiquement supprimé lorsqu’on essaie de l’utiliser. Ce qui veut dire qu’il y a une valeur minimum à l’option ioReadMaxData pour ne pas empêcher le bon fonctionnement des applications.

Renforcement de la lecture des objets – affichage

Suite de l’article sur le Renforcement de la lecture des objets, et type hash invalide.

L’argument $permitTruncate ayant disparu, c’est aussi l’option displayUnverifiedObjects qui n’a plus de raison d’être. Les fonctions d’affichage qui auraient pu devoir afficher un objet trop gros pour le vérifier n’en verront plus dans tous les cas.

En échange, une nouvelle option permitCheckObjectHash est mise en place dans la bibliothèque nebule en PHP orienté objet.
Elle est utilisée dans la fonction _getUnprotectedContent(). Elle va activer la vérification de l’empreinte des objets lus, ou plutôt forcer la lecture de l’objet même si son empreinte est invalide ou non vérifiable. C’est le pendant de l’option permitCheckSignOnVerify ayant la même signification pour la vérification des liens. Elle a true comme valeur par défaut. Elle n’est pas modifiable par lien, pour changer sa valeur par défaut il faut modifier le fichier des options.
Cette option est critique, elle doit toujours rester par défaut à true !

Renforcement de la lecture des objets – type hash invalide

Dans l’article sur le Renforcement de la lecture des objets, il était question notamment de la possibilité de supprimer ou pas un objet dont on ne peut pas vérifier l’empreinte parce que le type de hash est soit inconnu soit non reconnu.

Lors de l’échec de la récupération du type de hash de l’objet, on essaye tout de suite, si l’option permitSynchronizeLinks est à true, de synchroniser rapidement les liens de l’objet. Puis on essaie de relire le type de hash de l’objet.

Une nouvelle option permitDeleteObjectOnUnknowHash vient d’être ajoutée. Elle a true comme valeur par défaut. Elle n’est pas modifiable par lien, pour changer sa valeur par défaut il faut modifier le fichier des options.
Cette option est critique, elle doit toujours rester par défaut à true !

La nouvelle option est utilisée par la bibliothèque nebule en PHP en programmation orienté objet (library POO) par les fonctions checkConsistency() et _getUnprotectedContent() de la classe Object. La fonction _getProtectedContent() ne prend pas en compte cette option, elle se base uniquement sur _getUnprotectedContent() pour la lecture de l’objet protégé et de la clé de déchiffrement associée.

L’implémentation de l’option est un tout petit peu différent ce que l’on peut attendre. Lorsque l’on recherche le lien du type d’empreinte d’un objet (avec la pondération sociale), si aucun lien n’est trouvé ou si le nom de l’algorithme de prise d’empreinte n’est pas reconnu, alors il y a deux possibilités.
L’option permitDeleteObjectOnUnknowHash est à :

  1. false. Dans ce cas les deux fonctions retournent tout de suite un résultat booléen négatif ou un contenu vide.
  2. true. Comme aucun algorithme n’est trouvé, on utilise l’algorithme définit par défaut et on continue le processus de vérification dans les deux fonctions. Si l’empreinte ne correspond pas avec cet algorithme, l’objet est supprimé. C’est une façon de donner une chance à un objet pour lequel les liens auraient été partiellement synchronisés.

Dans la bibliothèque nebule en PHP en programmation procédurale (library PP), la lecture des objets se fait via les fonctions _o_ls1 et _o_lsx. La deuxième repose en fait sur la première. Et en début de fonction _o_ls1, un appel à la fonction _o_vr permet de vérifier le contenu de l’objet.
La fonction _o_vr ne prend en compte que les objets avec un hash fait avec l’algorithme par défaut, aujourd’hui sha256. L’option permitDeleteObjectOnUnknowHash n’est pas utilisée.

Dans les deux bibliothèques, si c’est l’objet avec d’identifiant 0, alors il est systématiquement supprimé.

Enfin, dans tous les cas, il ne faut surtout pas tenter de vérifier l’empreinte avec tous les algorithmes disponibles, cela reviendrait à permettre une attaque sur le plus faible de ceux-ci…

Renforcement de la lecture des objets

Dans la bibliothèque nebule en PHP orienté objet et dans certaines applications, un certain nombre de fonctions lisent le contenu des objets soit directement soit via la fonction getContent() de l’instance Object des objets. Toutes les lectures de contenus d’objets et de liens se font via la classe io de la bibliothèque et non directement par des fonctions de PHP de lecture de flux, de lecture directe. Les fonctions de la classe io ne font pas d’opérations cryptographiques, donc aucune vérification n’est possible à ce niveau.

Dans la bibliothèque se trouve aussi la fonction checkConsistency() pour vérifier le contenu d’un objet. Deux différences existent entre les deux fonction :

  1. La fonction getContent() lit des données et vérifie si l’empreinte est bonne sauf si l’objet est trop grand. Si l’objet est trop grand, un argument $permitTruncate permet de ne pas rejeter le contenu de l’objet si il est trop grand. Pour les petits objets la vérification se fait dans tous les cas. La limite d’un objet petit ou grand est définie par l’option ioReadMaxData. Si l’empreinte ne correspond pas, le contenu n’est pas conservé et un contenu vide est renvoyé à la fonction appelante. La fonction checkConsistency() ne renvoie pas de données mais vérifie juste l’empreinte, le résultat booléen renvoyé et négatif ou positif.
  2. La fonction getContent() ne supprime pas un objet si l’empreinte n’est pas bonne. La fonction checkConsistency() vérifie l’empreinte et, si l’empreinte n’est pas bonne, supprime l’objet via une fonction de la classe io.

Il est difficile de prendre une décision de suppression d’un objet parce que peut-être que l’algorithme de prise d’empreinte n’est pas reconnu par la machine sur laquelle tourne l’instance serveur. En cas d’absence de possibilité de vérification comme un type d’empreinte inconnu ou un objet trop grand, il faut renvoyer un contenu vide ou résultat négatif mais il ne faut pas supprimer l’objet. Quoique dans un mode paranoïaque, il faut peut-être prévoir de supprimer tout objet non vérifiable, à voir.

Pour commencer l’argument $permitTruncate n’a pas de raison d’être, il est contre productif parce qu’il affaibli l’ensemble du système. Il va être supprimé et les applications qui affichaient un objet avec un message comme quoi l’objet est trop gros vont afficher un message d’erreur sans le contenu.

Ensuite, la fonction getContent() fait appel à une fonction privée _getProtectedContent() pour lire le contenu d’un objet protégé. Elle va maintenant sous-traiter aussi la lecture des objets non protégés à une fonction privée _getUnprotectedContent(). Cette nouvelle fonction sera très similaire à la fonction checkConsistency() mais renverra un contenu complet ou vide au lieu d’un résultat booléen. Et bien sûr l’objet sera supprimé en cas d’empreinte invalide. Et la fonction _getProtectedContent() utilisera la fonction _getUnprotectedContent() pour la lecture de tous les objets accessibles non protégés.

La suppression de l’argument $permitTruncate va poser un gros problème pour l’affichage des gros objets. Ceux-ci via le navigateur peuvent être affiché dans certains cas parce que le navigateur les télécharge sur le serveur web pour les afficher au fur et à mesure. C’est le cas des vidéos non protégées. Une des options pour résoudre ce problème est peut-être d’utiliser le lien de type s jusque là inexploité par la bibliothèque…

Entités de recouvrement

Le mécanisme de recouvrement des objets protégés et des liens dissimulés est en train d’être doucement mis en place.

D’un point de vue théorique, cela répond à deux problèmes similaires.
En entreprise, et pas que, il est recommandé d’utiliser une ou plusieurs autorités de recouvrement lorsque l’on utilise de la cryptographie pour protéger ses données. Les décideurs le prennent souvent comme une contraite et oublient de mettre en place ce mécanisme de restauration des données chiffrées. Et ce mécanisme est différent de celui de restauration classique alors qu’il est perçu comme étant le même. Résultat, lorsqu’un employé critique vient à manquer, ses données, critiques aussi, deviennent subitement inaccessibles. La disponibilité c’est aussi de la sécurité.
Pour différentes raisons, des états plus ou moins démocratiques peuvent imposer la mise en place d’un mécanisme de déchiffrement des données de leurs concitoyens.

Mais, afin de ne pas rompre la confiance, ce mécanisme doit être loyale, c’est à dire public, transparent et vérifiable.

D’un point de vue pratique, la mise en place comprend deux parties.
Il faut commencer par recenser les entités éligibles comme autorités de recouvrement. Pour l’instant dans le code de la librairie en php, la liste de ces entités est renvoyée vide. Les applications peuvent donc commencer à prendre en compte ces entités pour l’affichage public. C’est le cas dans klicty mais pas encore dans sylabe.
Il faut ensuite, lors de la protection d’un objet ou de la dissimulation d’un lien, dupliquer la protection ou le lien pour chacune des entités de recouvrement. Cela revient simplement à faire un partage de la protection pour un objet protégé en duplicant le lien de type k de chiffrement de la clé de session.

Pour terminer, la librairie n’intégrera pas par défaut d’entité de recouvrement. Si des entités sont définies comme tel, ce sera uniquement par choix (ou obligation) de l’entité responsable du serveur.

Sondages et votes

Dans un article La Suisse pourrait imposer l’open-source pour le vote électronique de Numerama, il est de nouveau question de la mise à disposition du code source du programme sous forme de logiciel libre.

L’avenir du vote électronique ne fait aucun doute, seule sa réalisation pose problème aujourd’hui. Beaucoup de débats comparatifs et contradictoires ont lieux vis-à-vis de la pertinence du vote électronique et de la confiance que l’on peut apporter aux machines de vote et au processus dans son ensemble. Ces débats peuvent paraître très conservateurs mais ils sont néanmoins nécessaires puisque le vote est un acte fondamental de nos démocraties, c’est le moyen d’expression de chacun d’entre nous.

La confiance en ce genre de machine de vote et du code qui l’anime ne peut être assurée sans l’ouverture du code à minima en lecture. Il faut aussi connaître précisément l’environnement de compilation et d’exécution pour le code soit parfaitement reproductible. Et bien sûr, il faut être sûr ce c’est bien ce code qui a été utilisé et pas un autre.
Invoquer le secret industriel sur du code pour un processus parfaitement connu et un enjeu majeur de démocratie, c’est particulièrement malhonnête. Tout au plus une société éditrice peut-elle demander un droit de paternité et une restriction de commercialisation à son seul bénéfice. Mais il suffit à l’état qui fait la commande du code de demander, et payer, explicitement la libre diffusion ou la libéralisation complète du code.

Le code doit être capable dans son ensemble de permettre la centralisation des votes, l’anonymisation des électeurs ainsi que la vérification en temps réel et à postériori du décompte des votes. L’authentification de l’utilisateur devrait être le principal problème mais il apparaît que c’est en fait le décompte et sa vérification qui interpellent le plus souvent les détracteurs du vote électronique.

Un vote a un point de départ dans le temps et une fin à partir de laquelle le décompte des votes est considéré comme définitif.

L’anonymisation est aussi un problème pour la vérification de conformité du vote à postériori puisqu’elle casse le lien sûr entre le votant et le vote unitaire. On peut ainsi affirmer que le votant à voté (il a posé un papier et signé le paraphore) mais on ne peut pas le prouver à postériori (était-ce vraiment lui).
La capacité de multi-entité et la dissimulation de liens dans nebule permettent de résoudre ce problème.

Voici un scénario possible de vote avec les objets et liens de nebule :

  1. Pour un vote, une entité maîtresse du vote est générée. Elle est explicitement reconnue par les autorités comme telle. Son seul rôle est de générer les jetons de vote et de les attribuer aux électeurs.
  2. L’entité maîtresse du vote va générer autant d’objets jetons qu’il y a de votants. Ces jetons sont aléatoires et n’ont pas de relation directes avec les électeurs. Chaque jeton est en fait la partie publique d’un bi-clé cryptographique (RSA par exemple). La clé privée de chaque jetons est protégé par un mot de passe stocké dans un objet protégé par et pour l’entité maîtresse (dans un premier temps).
  3. Le jeton est en fait l’entité qui réalisera le vote via la clé privée. Chaque vote peut être vérifié par rapport au jeton, c’est à dire la clé publique.
  4. Pour chaque objets de clés privées de chaque jetons, l’entité maîtresse va partager le secret de chiffrement de l’objet contenant le mot de passe. Le lien entre objet chiffré et objet non chiffré est dissimulé, c’est à dire que c’est un lien de type c masquant le vrai lien.
  5. La clé privée de l’entité maîtresse est détruite. Il n’est ainsi plus possible de retrouver l’intégralité des relations en les jetons et les électeurs mais il est possible de vérifier que tous les électeurs ont reçus un lien dissimulé et de vérifier tous les jetons réalisant le vote.
  6. Pour un vote, une entité de décompte du vote est générée. Elle est explicitement reconnue par l’entité maîtresse Son seul rôle est de recueillir et de valider les votes. La période de vote démarre.
  7. L’électeur, c’est à dire l’entités votantes, va récupérer auprès de l’entité maîtresse du vote l’intégralité des jetons et des clés privées associées (et pas juste son jeton). Il va ainsi obtenir tous les liens dont le lien dissimulé le concernant. Via le lien dissimulé, il va savoir quel est la clé privée du jeton que l’entité maîtresse lui a attribué. Disposant de cette information il peut déprotéger à son profit l’objet contenant le mot de passe de la clé privée du jeton.
  8. L’électeur, mettant à profit la clé privée du jeton, peut réaliser un ou plusieurs votes, seul le dernier est pris en compte. Le vote consiste en un lien entre le jeton et le choix de vote dans le contexte de l’entité de décompte du vote (champs méta).
  9. L’entité de décompte du vote vérifie régulièrement auprès de tous les électeurs la présence de liens dont elle est le contexte. au fur et à mesure de la récupération des liens, elle se les approprie (signature du lien de vote).
  10. A la fin de la période de vote, la clé privé de l’entité de décompte du vote est détruite. Plus aucun vote ne peut être ajouté, modifié ou supprimé. Les votes comptabilisés sont ceux qui ont été signés par l’entité de décompte du vote.
  11. L’électeur qui souhaite rendre publique son vote a juste à prouver qu’il dispose du jeton en utilisant sa clé privée pour autre chose que le vote en relation avec sa véritable entité. Il peut aussi révéler le lien dissimulé que lui avait généré l’entité maîtresse du vote.

Un des aspects des liens dissimulés est qu’il est possible de les dissimuler pour plusieurs entités. Ainsi il est possible de générer une entité d’audit du vote à qui l’entité maîtresse partagera les liens dissimulés, de façon également dissimulé.L’entité d’audit devient capable à postériori de vérifier la bonne association entre jetons de vote et électeurs sans être elle-même capable d’émettre de nouveaux jetons.

Le sondage est moins contraignant et surtout peut être à choix multiples.

Caliopen

Depuis le début de Caliop ou pas loin, je regarde ce qui s’y passe. Aujourd’hui ce projet de messagerie sécurisée continue sous Caliopen.

Ce n’est pas un service tout à fait comparable à ce que propose nebule. C’est un service qui se veut compatible avec la messagerie smtp. Cela implique la présence et l’utilisation de serveurs centraux de messagerie. Ensuite, si l’interface mélange les différentes sources de messages comme SMS, emails et tchats, il ne semble pas y avoir d’autres moyens d’échange ou de gestion de l’information.

Dans l’interface proposée, il y a une chose intéressante. Dans la vue de boite d’entrée, on a deux curseurs permettant de montrer les messages.

Le premier curseur gère le niveau de sécurité des messages affichés. Lors des échanges de messages, on doit s’attendre à ce que la confiance dans le contenu des messages soit forte ou à défaut qu’un indicateur de cette confiance pondère son contenu. Il est un peu étonnant qu’il y ai un seuil haut et bas. Quel sera l’usage du seuil haut que l’on abaisserait ? Le niveau de confiance d’un message est calculé sur la façon dont il est transmis, le réseau proche utilisé, et la cryptographie employée.
Dans nebule, cette confiance n’est pas vraiment calculée. Les réseaux utilisés et les serveurs parcourus ne sont pas source de calcul d’une confiance. Ils ont par défaut une confiance nulle. C’est la façon de parcourir de multiples serveurs de façon aléatoire qui va palier au manque de confiance dans les réseaux et les serveurs. Par contre, un curseur social sera définit et les liens seront triés en fonction de seuils. Et ce curseur dépendra surtout de l’entité avec qui on correspond. Une pondération automatique sera possible pour les entités inconnues en fonction des entités connues qui la reconnaissent. Pour la cryptographie, chacun peut librement choisir ce qu’il utilise et ce qu’il protège, c’est comme pour Caliopen.

Le second curseur gère l’importance des messages avec un seuil haut et bas. là aussi il y a un seuil haut dont l’usage est à voir en pratique. L’importance est donnée par l’émetteur du message.
Dans nebule, l’importance n’est pas fixée par l’émetteur mais est calculée en fonction de l’émetteur et des liens vers des objets pondérés. Il est même possible de simuler en public une importance forte à une entité en particulier mais en réalité de dissimuler que cette entité n’en a pas.

La découverte de nouvelles personnes avec qui converser se fait par divers moyens. Mais il faut bien vérifier la clé publique. Caliopen propose d’utiliser le DNS. Tout le monde peut contrôler un nom de domaine ou appartenir à un nom géré par quelqu’un d’autre. Il est possible de transmettre par ce biais une clé publique pour une adresse (email) correspondante. On rend difficile l’usurpation d’une identité.
Avec nebule, en l’absence de vérification directe d’une entité et donc d’une pondération forte, on fait confiance à des entités proches pour pondérer cette entité que l’on ne connais pas. C’est un peu le système utilisé dans PGP.

Je continue à regarder l’évolution du projet en espérant qu’il ne capotera pas comme tant d’autres…

Cosignature – orientation

Dans la continuité de la réflexion sur la cosignature et suite.

Une des possibilités que doit permettre la cosignature, c’est que l’on puisse créer une signature (ou assimilé) valide alors que les différentes personnes (et leurs entités) ne sont pas réunies en même temps au même endroit pour réaliser cette signature commune.

Le système classique pour résoudre la cosignature consiste en la répartition du secret suivant le schéma de seuil de Shamir.

Cette solution de partage du secret n’est pas suffisante pour deux raisons.

Pour commencer, cela veut dire que l’on n’a toujours qu’un seul secret mais qu’il est répartit, dilué, entre plusieurs entités. Lorsque l’on veut faire une signature, il faut réunir un minimum de ces entités au même endroit pour accéder au secret qui permettra la signature. A ce moment, le secret est extrêmement vulnérable.
Il faut réaliser une sorte de cérémonie des clés pour cela.

Enfin, la génération du secret est réalisé par un seul équipement et ensuite répartit. Il faut ici aussi une cérémonie des clés avec tous les porteurs d’une partie du secret. Si il n’est pas possible de réunir tout le monde, une partie du secret doit être transmis de façon sûr vers le porteur concerné. Mais il ne peut pas dans ce cas garantir par lui-même que personne n’a copié sa partie du secret. Et surtout il ne peut garantir que personne n’a volé le secret complet lors de la cérémonie des clés.

Donc, il faut que chaque porteur génère sa partie de clé, on génère un bi-clé qu’il garde, et dont il peut garantir la confidentialité. Ensuite, il reste à réaliser le mécanisme intermédiaire qui permet, en ne connaissant que les clés publiques des porteurs, de valider une pseudo signature réalisée par chacun des porteurs. Une pseudo signature qui n’impose une présence ni spatial ni temporelle des porteurs.

Liens :
https://fr.wikipedia.org/wiki/Partage_de_cl%C3%A9_secr%C3%A8te_de_Shamir
http://www.kilomaths.com/2010/07/partage-de-secret/

Cosignature – suite

Suite de l’article sur la Cosignature.

La notion de groupe est intéressante puisque pour l’instant, si le groupe a été définit dans sa ou ses formes, il n’a pas été définit dans son implémentation.

Cette implémentation peut rejoindre la notion de cosignature. En étendant la notion d’entité à autre chose que des bi-clés cryptographiques, notamment à un fichier de description du groupe et de la validité de sa signature (équivalente), on crée implicitement un groupe. Ce groupe hérite de par ses propriétés internes d’une capacité de signature et de vérification. Comme ce n’est pas un bi-clé cryptographique, il n’y a pas d’objet de clé privée. L’objet définissant le groupe n’est pas suffisant en lui-même pour signer des liens, il doit se reposer sur les ‘vraies’ entités qui composent le groupe.

Par exemple, la forme du fichier définissant un groupe de 3 entités peut être un objet contenant :

[Members]
88848d09edc416e443ce1491753c75d75d7d8790c1253becf9a2191ac369f4ea
01351dd781453092d99377d94990da9bf220c85c43737674a257b525f6566fb4
19762515dd804577f9fd8c005a7803ddee413f264319748e30aa2aedf318ca57
[Signe]
(88848d09edc416e443ce1491753c75d75d7d8790c1253becf9a2191ac369f4ea . 01351dd781453092d99377d94990da9bf220c85c43737674a257b525f6566fb4)
+
(19762515dd804577f9fd8c005a7803ddee413f264319748e30aa2aedf318ca57 . 88848d09edc416e443ce1491753c75d75d7d8790c1253becf9a2191ac369f4ea)
+
(01351dd781453092d99377d94990da9bf220c85c43737674a257b525f6566fb4 . 19762515dd804577f9fd8c005a7803ddee413f264319748e30aa2aedf318ca57)
[Timestamp]
2015-05-28T22:20:13+0200

La signification du groupe, c’est que les membres sont 3 et que la signature d’un lien par deux des trois entités est valide comme étant celle du groupe ( (1 et 2) ou (2 et 3) ou (3 et 1) ).

Ce n’est qu’un exemple…

Cosignature

Une réflexion depuis quelques temps porte sur la cosignature (cf Les entités et le code / Redéfinition de puppetmaster). Et elle est toujours d’actualité. Le but est de permettre d’avoir une entité unique mais dont la clé privée soit répartie en plusieurs morceaux, chaque morceau sous la responsabilité d’une personne différente. On doit avoir plusieurs entités qui peuvent communément, et non individuellement, signer pour l’entité unique.

Le problème peux être résolu en ayant un mécanisme qui valide la signature de l’entité unique par la présence d’un nombre pré-définit de signatures d’entités pré-validées. On n’a plus dans ce cas une entité mais un groupe d’entités dont la cosignature est reconnue comme signature du groupe. Dans ce cas, la notion d’entité s’étend et ne sous-entend plus seulement un objet avec une clé cryptographique mais un objet qui constitue un groupe d’entités avec des règles de fonctionnement.

Jusqu’ici, je n’ai trouvé que des solutions matériels avec un seul bi-clé cryptographique conservé dans une puce et dont l’usage est contraint par l’authentification de plusieurs personnes physiques. Ce n’est pas satisfaisant puisque toutes les personnes doivent être présentes au même endroit au même moment pour activer la clé privée. Les solutions de cosignatures que j’ai trouvé se contentent de gérer de multiples signatures d’un document mais sans gérer cette notion de communauté.

Description de la création d’une nouvelle entité.

La ré-implémentation de la génération d’une nouvelle entité est en cours dans sylabe.

Une nouvelle partie apparaît dans la documentation de référence sur la création d’une entité : Wiki – Documentation nebule v1.2 – Création d’une entité

On y trouve la procédure de référence à implémenter et notamment tout ce qui concerne la manipulation des clés cryptographiques asymétriques et mots de passes.

Mémorisation de liens et accélération des traitements

Par défaut, à chaque chargement d’un objet pour traitement ou pour son affichage, chaque liens sont lus et vérifiés, puis relus et revérifiés. Parce que cette vérification implique des algorithmes cryptographiques de prise d’empreinte et des algorithmes cryptographiques asymétrique (à clés privées), le traitement cumulé de chaque vérifications devient vite une quantité non négligeable. Bref, le temps de calcul se ressent dans le traitement.

Il est possible d’accélérer ce fonctionnement avec la mémorisation des vérifications déjà faites.

Pour commencer, on peut considérer en première approximation que la plus grande partie du temps de traitement est imputable à la cryptographie asymétrique. On considère donc par défaut que les autres traitements sont, temporellement, quantités négligeables. cette approximation est vérifiée en pratique dans sylabe lorsque l’on désactive la vérification des signatures.

Pour des raisons de sécurité, les liens qui ont été vérifiés, et que l’on souhaite mémoriser, doivent être mémorisés en intégralité. Il ne faut pas garder uniquement la signature du lien. Il est préférable de conserver l’intégralité du lien. Tout au plus peut-on supprimer le champs signature. Ces liens pré-vérifiés doivent être conservés en lieu sûr, non modifiable par une autre entité ou un autre processus.
Dans ce cas, la vérification d’un lien va commencer par le parcours des liens déjà vérifiés, puis en dernier recours à vérifier le lien. Au delà d’un certain nombre de liens mémorisés, il est possible que le bénéfice de la mémorisation soit négatif vis-à-vis de la vérification direct des signatures des liens. Il faudra montrer expérimentalement l’ordre de grandeur de la table des liens mémorisés. Qui dit table de mémorisation limité dit aussi gestion de la quantité de liens mémorisés et donc du remplacement de certains liens par d’autres. Ce remplacement peut se faire en boucle, sans calcul, ou au contraire en tenant compte du temps de dernier usage des liens mémorisés. Bref, il y a du travail d’optimisation en perspective.

Comme on l’a vu avec une table de mémorisation limitée, le temps de mémorisation des liens peut être variable. De même, une autre période de rétention peut exister. La table de mémorisation peut n’être valable que pour le temps de chargement d’une page (web). Ou au contraire la table de mémorisation peut être valable le temps de la session, c’est à dire tout le temps ou l’entité est déverrouillée. Dans le cas de navigations sur sylabe, et en étant non-déverrouillée, la mémorisation peut être liée à la session php, et donc expirer avec celle-ci.

Imaginons maintenant un peu le futur. Imaginons que chaque entité, chaque humain dispose de sa clé privée en permanence dans un périphérique, ou plutôt une prothèse. Empactée dans du matériel, la clé privée serait beaucoup mieux protégée. De fait, corrompre la table de mémorisation des liens vérifiés deviendra un moyen plus facile pour modifier le comportement d’une entité. Il doit donc être maintenu la possibilité de fonctionner en mode paranoïaque en vérifiant à chaque utilisation les liens.

Cryptographie et clé de session

Dans nebule, à chaque fois que de la cryptographie intervient avec des entités d’un côté et du contenu de l’autre, on utilise de la cryptographie asymétrique et de la cryptographie symétrique.

La clé de session est l’un des éléments importants. Elle assure en quelque sorte le lien entre l’entité et le contenu. Le contenu peut être soit un objet soit un lien. La clé de session, c’est le mot de passe de la cryptographie symétrique pour chiffrer/déchiffrer le contenu. La clé de session est chiffrée/déchiffrée avec respectivement la clé publique ou la clé privée d’une entité.

La clé de session est le pivot du processus de chiffrement. Elle aurait pu être intégrée au contenu chiffré, ce qui nécessite une extraction pour le déchiffrement. Mais au titre de pivot, dans nebule elle est volontairement mis en avant et isolée plutôt que cachée comme une banale donnée technique.

Lors du processus de chiffrement d’un objet, la clé de session est un objet à part entière et lui aussi chiffré avec une clé privée d’entité.

20130209 nebule - schema crypto

Lors du processus d’offuscation d’un lien, son chiffrement en fait, la clé de session aurait pu aussi être fusionnée dans le registre avec le champ contenant le lien chiffré LienChiffré. Mais au contraire, elle occupe un champ à part entière CléSession.

Signature_Signataire_TimeStamp_c_EntitéCible_LienChiffré_CléSession

Cette sanctuarisation de la clé de session entraîne apparemment une plus grande complexité des processus de chiffrement. Cependant, cela apporte une grande simplification dans la gestion des objets chiffrés, mais rien pour la gestion des liens offusqués. Si un objet chiffré doit être partagé avec plusieurs entités, une clé de session différente entraînerait la nécessiter de rechiffrer l’objet source pour tous les destinataires, càd le chiffrement symétrique et asymétrique. Avec une clé de session autonome, il suffit juste de la rechiffrer pour tous les destinataires la clé de session, donc juste opération de chiffrement asymétrique. Pour un petit objet, le gain est négligeable, mais il ne l’est pas pour un gros objet (plusieurs fois la taille de la clé de session).
Je rappelle que le chiffrement asymétrique est beaucoup plus gourmand en ressources processeur et en mémoire que le chiffrement symétrique.

On peut aussi imaginer que la clé de session soit réutilisée pour le chiffrement de plusieurs objets ou de plusieurs liens. Si c’est pour une seule entité, cela permet de ne réaliser le chiffrement asymétrique qu’une seule fois. Cela crée une sorte de groupe d’objets ou de liens, ceux-ci regroupés par leur clé de session commune. Il est aujourd’hui possible d’envisager deux cas où plusieurs objets ou plusieurs liens pourraient utiliser la même clé de session :

  1. La diffusion d’objets très fortement liés entre eux et qui auraient tout intérêts à « voyager » ensembles. Idem pour des liens fortement couplés comme lors de la nébulisation d’un objet.
  2. L’utilisation de matériels peu performants pour lesquels il serait incontournable de n’avoir à calculer qu’un seul chiffrement asymétrique pour plusieurs objets et/ou plusieurs liens.

Il faut cependant garder à l’esprit que ces deux cas entraînent un risque sur la divulgation de ces objets et liens. Si un seul d’entre eux est retransmit pour autrui, c’est à dire que sa clé de session est repartagée, alors c’est tous les autres qui sont de fait divulgués. Ces exceptions doivent être évitées à tout prix ou toujours utilisées avec intelligence et extrêmes précautions.

Une clé de session doit toujours être robuste et utilisée pour un seul objet ou un seul lien.

Prise d’empreinte homomorphique

Les objets manipulés par nebule sont identifiés, et donc référencés, par leurs empreintes respectives. Ces empreintes sont cryptographiques afin de pouvoir s’assurer que c’est bien le bon objet, afin de pouvoir avoir confiance dans l’intégrité de son contenu. Il est possible dans un seul cas d’avoir plus d’une empreinte par objet, c’est si celles-ci sont calculées avec des algorithmes différents (cf Collisions d’empreintes multi-algorithmique).

Cependant, si la propriété cryptographique des empreintes est indispensable à la confiance, elle entraîne un manque de souplesse dans le référencement des objets. Rien dans la valeur de l’empreinte ne trahis une partie de son contenu. L’empreinte cryptographique reflète uniquement l’intégralité de l’objet. On ne peux pas s’en servir pour retrouver des objets proches dans leur contenu. Tout au plus peut-on vérifier si deux objets sont identiques… ce qui n’a pas d’intérêt puisque dans ce cas c’est tout simplement le même objet.

Sub-division d’objet

La première solution pour résoudre ce problème est d’utiliser des sous-parties d’un objet comme des objets propres, et de les identifier comme tels. Le lien de type s permet justement de lié l’objet principal à ses morceaux.

C’est notamment ce qui est fait dans les logiciels de Paire-à-Paire (P2P – Peer to Peer). Pour qu’un fichier puisse être téléchargé depuis de multiples sources, celui-ci est pré-découpé en morceaux de taille identique pré-définit. Chaque morceau à une empreinte propre et peut être vérifié à la réception. Chaque morceau est téléchargé sur une et une seule source, mais plusieurs morceaux sont téléchargés simultanément depuis plusieurs sources. On augmente ainsi le débit réel de réception du fichier voulu même si les sources ont individuellement un faible débit d’émission. Évidemment, si chaque morceau est valide, le fichier dans son ensemble ne peut qu’être valide.

Une recherche sur mot clé peut avantageusement tirer partie de ce système puisqu’une recherche se fera uniquement sur l’empreinte du morceau correspondant à la recherche. Toute la difficulté est de bien choisir ces morceaux.

Pour du texte, c’est facile. Pour une recherche sur des images ou des vidéos, c’est déjà beaucoup moins évident. Mais quoique l’on trouve, c’est toujours une liste d’objets qui contiennent cette petite sous-partie même si le reste n’a absolument aucun rapport.

Empreinte homomorphique

Une autre solution consiste à essayer de trouver des objets qui ont le plus de contenu en commun. Ce serait une sorte de représentation miniature du contenu de l’objet. On veut quelque chose qui se rapproche plus de l’empreinte des doigts de pieds. On regarde d’abord que cela à bien la forme d’un pied, puis on regarde plus en détail certaines parties morphologiques pour déterminer si les deux pieds sont proches.

On pourrait partir sur le système de sous-découpage utilisé par le P2P. Chaque objet est découpé en petits morceaux de taille identique. Ainsi, si deux objets ont un ou des morceaux en commun, on pourra en déduire que ceux-ci sont proches.
Mais cette méthode pose un problème. Si on prend un objet et que l’on en fait une copie avec pour seule différence un caractère supplémentaire dans le premier bloc de données, alors tous les blocs seront vus comme différents alors que les objets ont clairement des parties communes.
On pourrait imaginer essayer d’optimiser la méthode en travaillant sur des blocs de tailles variables. Mais quels critères adopter pour ajuster les tailles de blocs en fonction des données ?

Je propose une méthode comme base de réflexion à défaut pour l’instant d’être adoptée.
Si on regarde le travail d’un logiciel de compression de données, on constate qu’il recherche les occurrences multiples de données dans l’ensemble d’un document. Il le fait sans tenir compte de la sémantique de ce qu’il trouve. Ainsi des mots très proches sémantiquement ne seront pas agrégés parce que différents. Ensuite, le logiciel de compression fait un classement statistique pour déterminer les occurrences multiples qu’il serait avantageux de réduire. Une phrase qui apparaît quelques fois permet une bonne optimisation. Un mot qui apparaît plusieurs permet aussi un gain de place facile.
Si on reprend le même principe d’analyse, même sans tenir compte de la sémantique des mots, on peut s’attendre à ce que les plus grandes occurrences de mots ou de phrases représentent le ou les sujets du document. C’est ce que fontnotamment les moteurs de recherches (Google, Bing, Yahoo…) lorsqu’ils moulinent les pages web, mais avec l’analyse sémantique en plus.
L’empreinte homomorphique est constituée des 20 premières occurrences redondantes avec leur poids respectifs. L’occurrence peut être représentée par une petite empreinte (CRC) de façon à avoir une taille fixe, mettons 16 caractères hexadécimaux. Le poids peut être représenté en pourcentage sur 4 caractères hexadécimaux (entre 0000 et ffff).
Vue comme ça, l’empreinte générée n’est plus tout à fait homomorphique et n’a pas de propriétés cryptographique.On obtient une empreinte homomorphique de 400 caractères hexadécimaux.

Ainsi, plusieurs documents parlants d’un même sujet ont de fortes chances d’avoir une même empreinte parque bien que différents ils auront les mêmes occurrences redondantes.

Un certain nombre de données annexes vont figurer dans les données utilisées pour la comparaison. Par exemple on peut retrouver les en-têtes internes des documents bureautique. Il faut peut-être pré-filtrer les documents en fonction de leur type pur. Par exemple, un simple fichier texte et un fichier complexe de traitement de texte se verront expurgés de tout ce qui est en-tête et données internes, puis on en gardera que les caractères imprimables convertis en minuscule, sans ponctuation…

Conclusion

Une empreinte homomorphique peut être utilisée avantageusement en complément de l’empreinte cryptographique. Elle n’a d’intérêt que pour des objets ayant suffisamment de contenu. Il faut prévoir un seuil minimum en dessous duquel elle n’est pas calculée. Cette empreinte homomorphique est liée à l’objet par un lien de type l avec comme objet méta « nebule/objet/homomorphe ». Cet objet à usage réservé est ajouté à la documentation.

Mais dans tous les cas, en l’absence de propriétés cryptographique, une empreinte homomorphique ne doit pas être utilisée dans les liens. L’usage n’est pas le même, on fait soit de l’intégrité, soit du référencement.

Détournement de liens de mise à jour

La mise en place dans sylabe du code nécessaire à la résolution du graphe des mises à jours d’un objet montre que l’on peut créer une sorte de raccourci d’objet.

Ce détournement ne pose à priori pas de problème puisqu’il sera impossible de créer un objet avec cette empreinte réduite et que toute tentative se traduira par un rejet de l’objet lors de la vérification d’intégrité.

Abandon de certains liens lors du chiffrement

Maintenant que l’IV est utilisé par défaut avec une valeur nulle, il n’a plus à être précisé. Le lien qui était généré vers l’objet nebule/objet/encode/InitialVector pour le préciser n’a plus de raison d’être utilisé.

Il en est de même pour la clé de session. L’objet de la clé de session apparaît naturellement dans les deux liens de chiffrement. Il n’est donc pas nécessaire de re-préciser que c’est une clé de session. Il n’est d’ailleurs pas utilisé dans le processus de déchiffrement. Le lien vers nebule/objet/encode/SessionKey ne sera donc plus généré.

Et de fait, l’objet nebule/objet/encode n’a plus d’utilité non plus. La documentation de nebule v1.1 est mise à jour en conséquence. On supprime ces objets réservés :

  • nebule/objet/encode
  • nebule/objet/encode/InitialVector
  • nebule/objet/encode/SessionKey

OpenSSL et la cryptographie – suite

Voici la suite sur les problèmes d’implémentations de la cryptographie symétrique tel que décris dans OpenSSL et la cryptographie et Interopérabilité du chiffrement(blog sylabe).
Après quelques tests sur le chiffrement symétrique avec la commande openssl et son équivalent en php, j’ai trouvé les bonnes implémentations pour obtenir le même chiffre à partir des mêmes valeurs en entré.

Il y a à la fois une erreur dans l’implémentation de openssl dans nebule en bash, et une autre erreur d’implémentation de openssl dans sylabe en php.

BASH

En bash, la commande openssl enc était appelée avec l’option -kfile alors qu’il faut utiliser l’option -K.
Il faut en plus utiliser l’option -nosalt pour ne pas ajouter de sel et donc notamment avoir un objet chiffré de taille strictement identique à l’objet en clair.

Voici une courte implémentation qui marche, dans le cadre d’emploi de nebule exclusivement :

#!/bin/bash
nebule_symalgo="aes-256-ctr"
iv='00000000000000000000000000000000'
echo -n "477fd3f3a32dc5de70cf13d1e46d8663f5f23873826572ea8359064b6d63c60c2d76f29a5e34fac2aebb157975517ef23110f4a5e415d9d0408f6fe7b9fe17bdd6bbb2df3fb819ecbd5216835ecccc559e7eb84e0517e92538d9a81fec333498a64b90df3429abe857ba1666fc93b24509e63d05fd619da9eef12c8d70dbacca" > /tmp/bdata
key='8fdf208b4a79cef62f4e610ef7d409c110cb5d20b0148b9770cad5130106b6a1'
openssl enc -e -$nebule_symalgo -in "/tmp/bdata" -out "/tmp/bcode" -K $key -iv $iv -nosalt -p
sha256sum /tmp/bcode

PHP

En php, la commande openssl_encrypt recevait la clé de chiffrement hexadécimale alors qu’il faut la transmettre sous forme binaire.
Par défaut, aucun sel n’est utilisé.
Enfin, l’IV peut avoir une valeur nulle contrairement à ce qu’affirme la documentation. Ce doit être une erreur de traduction. La valeur de doit pas avoir une taille nulle.

Voici une courte implémentation qui marche, dans le cadre d’emploi de nebule exclusivement :

<?php
$nebule_symalgo = 'aes-256-ctr';
$data="477fd3f3a32dc5de70cf13d1e46d8663f5f23873826572ea8359064b6d63c60c2d76f29a5e34fac2aebb157975517ef23110f4a5e415d9d0408f6fe7b9fe17bdd6bbb2df3fb819ecbd5216835ecccc559e7eb84e0517e92538d9a81fec333498a64b90df3429abe857ba1666fc93b24509e63d05fd619da9eef12c8d70dbacca";
$hiv='00000000000000000000000000000000';
$iv=pack("H*", $hiv);
$hkey="8fdf208b4a79cef62f4e610ef7d409c110cb5d20b0148b9770cad5130106b6a1";
$key=pack("H*", $hkey);
$cryptobj=openssl_encrypt($data, $nebule_symalgo, $key, OPENSSL_RAW_DATA, $iv);
$hashcryptobj=hash('sha256', $cryptobj);
echo "E=$hashcryptobjn";
?>

WatchDox

Un article de Wired parle de WatchDox, une (relativement) nouvelle solution de partage de données incluant une protection au niveau de la donnée elle-même.

En résumé, c’est un système type nuage (cloud computing) qui s’interface avec la suite Office de Microsoft et la visionneuse de PDF de Adobe. L’utilisation est donc assez pratique pour qui est full Microsoft, mais aussi assez bridée de fait.
Le véritable intérêt, et ce qui le démarque de la concurrence, c’est que la protection de la donnée se fait au niveau de la donnée elle-même. Ce n’est pas géré de façon globale sur un serveur par des droits génériques et hérités mais qui ne s’appliquent que sur le serveur.
Il est notamment possible d’interdire la retransmission d’un document ou son impression, et plus encore. Cela ressemble beaucoup comme ça à ce que permet le PDF si on utilise les outils de Adobe, justement…
Il y a aussi une fonctionnalité de traçage des consultations. Chaque destinataire légitime d’un document peut l’ouvrir. Le propriétaire, l’expéditeur, sait qui l’a consulté et quand.

Au début, je me dis que j’ai enfin quelque chose qui ressemble à nebule, une gestion et une sécurisation des documents pensées au niveau du document lui-même. Il va être possible de confronter les principes sous-jacents à nebule avec quelque chose de proche…

L’enchantement ne dure pas longtemps. Pour remettre tout de suite le contexte de WatchDox, la société n’est pas encore rentable avec 10M$ de revenus annuels.
Ensuite, oui on gère des droits de diffusion au niveau de chaque documents. Mais on est finalement loin de nebule dans le fonctionnement. La donnée est chiffrée et taguée avec des droits. Ces droits sont des droits dits faibles parce qu’ils vont à l’encontre d’une règle simple : toute information que l’on transmet, on en perd irrémédiablement le contrôle.
Alors, ou est l’ambiguïté ? C’est simplement que cette solution repose sur le programme qui gère les données. La cryptographie permet de s’assurer que la donnée ne sera pas volée en cours de transmission, mais la sécurité des restrictions de (re)partage des données ne tient que sur le programme. De plus, bien que l’on puisse imaginer un cache local des données chiffrées, il faut impérativement être connecté pour exploiter les données et ainsi permettre à la traçabilité de fonctionner.
Cela veut dire qu’il est impossible de rendre publique le code du programme ou même son fonctionnement. Sinon il deviendrait possible de concevoir un programme pour manipuler les données en récupérant (légitimement) la clé de chiffrement mais aussi par exemple en permettant d’outrepasser les restrictions de partage.
Cela exclu aussi de fait toute standardisation ou interopérabilité de cet outil à d’autres produits plus ouverts, une implémentation libre par exemple.

Cette solution ne peut donc prétendre interdire la perte d’information, c’est conforme à la théorie. D’ailleurs, l’article reconnaît qu’il est toujours possible de voler l’information qui s’affiche à l’écran, même en mode paranoïaque. Elle permet quand même d’augmenter sensiblement la difficulté du vol d’information. Il reste à voir comment la gestion des droits va se passer au bout de quelques années et avec plusieurs centaines de milliers de documents…
Il reste la partie chiffrement des données dans le nuage qui peut sérieusement justifier la mise en place d’une solution comme WatchDox. Mais quelle confiance peut-on avoir en un système pour lequel on ne peut espérer obtenir le fonctionnement réel, et donc sur lequel aucun audit de sécurité sérieux et impartial ne peut être mené ?

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…