Consignes

Le rendu de ce TP se fera uniquement par TPLab et consistera en une archive (zip, tar, etc.) contenant votre code et impérativement un fichier README.

Attention :

Tout non respect d'une ou plusieurs de ces consignes entrainera automatiquement un retrait de points sur votre note !

Langage de programmation

Le langage de programmation est libre mais vous devez vérifier avec l'encadrant si vous souhaitez utiliser autre chose que C, C++, Java, Python ou Javascript.

Par rapport au TP1, ce TP ne nécessite pas de calcul intensif. Ma version a été programmée en Python...

Liens utiles

Description du sujet

L'université NIHCAMCURT souhaite créer un service de création de diplômes numériques : les étudiants qui réussissent leurs master pourront récupérer un diplôme du genre :

Ce diplôme sera constitué d'une image avec les caractéristiques suivantes :

Votre tâche consiste à proposer une solution à cette demande pas très précise. Cela ce décompose en 2 parties, autant importante l'une que l'autre.

  1. Produire un document technique précisant les choix faits, les failles potentielles, les conseils pour une implémentation réelle ; ainsi que les suggestions d'amélioration.

  2. Un prototype qui permettra de vérifier que ce que vous proposez est effectivement réalisable.

Le document technique devra en particulier contenir :

1. Stéganographie

1.1. Description

Le premier point obligatoire du TP est la partie stéganographie dans l'image du diplôme.

Nous allons pour cela utiliser une technique classique et simple (mais assez mauvaise) qui consiste à cacher de l'information dans les bits de poids faibles des pixels d'une image ("LSB steganography").

Par exemple, le message

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.  Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

est caché dans l'image centrale.

TP2/chablais-orig.png TP2/chablais-lorem.png TP2/chablais-lorem-diff.png
image originale image avec message caché pixels modifiés

La technique est assez simple : la composante "rouge" des pixels de l'image est modifiée pour contenir un bit du message à caché. Plus précisément, le bit de poids faible de la composante "rouge" des pixels contient les bits du message.

La différence entre des pixels ayant uniquement leur bit de poids faible différent est indécelable à l'œil nu :

TP2/abcdef.gif TP2/abcdee.gif
couleur #abcdef couleur #abcdee

Si on accepte une perte de qualité, on peut utiliser 2, 3, ou même les 4 bits de poids faible. La seconde image ci dessous n'est pas très bonne, mais reste reconnaissable. Ses pixels cachent, dans leurs 4 bits de poids faible, une version "compressée" de l'image de gauche !

TP2/friedman-orig.png TP2/chablais-friedman.png TP2/chablais-friedman-diff.png TP2/friedman-result.png
image à cacher image avec stéganographie pixels modifiés image extraite

La différence de couleur dans ce cas est plus visible :

TP2/abcdef.gif TP2/a0c0e0.gif
couleur #abcdef couleur #a0c0e0

Dans l'exemple ci dessus, la différence entre l'image originale et celle avec des données cachées est visible essentiellement sur les zones unies (ciel et facade).

Voici le résultat si on utilise une image moins régulière :

TP2/arbre-orig.png TP2/arbre-friedman.png

La stéganographie BPCS permet d'utiliser en priorité les parties de l'image moins régulières pour cacher l'information et donne donc de meilleurs résultats :

TP2/friedman-orig.png TP2/chablais-friedman-BPCS.png TP2/chablais-friedman-BPCS-diff.png TP2/friedman-result.png
image à cacher image avec stéganographie BPCS pixels modifiés image extraite

C'est plus efficace, et plus marrant à coder ; mais plus complexe également...

1.2. Pour le TP

Écrivez un programme qui permet de cacher un message dans une image et de la récupérer.

N'oubliez pas de tester votre programme et d'inclure des exemples dans votre archive.

Attention, pour cette version naive de stéganographie, il est important d'utiliser un format d'image sans perte. En particulier, le format JPEG n'est pas utilisable...

Je vous conseille le format PNG. (Le format .ppm est aussi utilisable et a l'avantage de ne pas nécessiter de librairie...)

Pour ceci, vous pouvez utiliser une bibliothèque de manipulation d'image. Mon programme a été écrit en Python en utilisant la bibliothèque Pillow (fork de la bibliothèque PIL : Python Imaging Library).

2. Signature de données

2.1. Description

La signature de données électroniques se fait avec un mécanisme de clé publique / clé privée :

Le diplôme sécurisé doit contenir une signature afin qu'un utilisateur malveillant ne puisse pas créer un diplôme frauduleux.

La clé privée doit donc être créée par vous (représentant l'université NIHCAMCURT) et devrait rester secrète.

Plutôt que signer un fichier, les signatures valident en général son empreinte, calculée avec une fonction de hachage sure.

2.2. Pour le TP

  1. Créez une paire clé publique / clé privée pour pouvoir signer des données,

  2. écrivez un programme / script pour signer des données avec cette clé privée,

  3. écrivez un programme / script pour vérifier la validité d'une signature vis à vis de données existantes.

Attention, n'oubliez pas d'inclure vos clés dans l'archive du TP et de justifier les choix faits.

N'oubliez pas de tester votre programme et d'inclure des exemples dans votre archive.

3. Création du diplôme

3.1. Image et texte

Écrivez une fonction qui génère un diplôme simple (sans composant cryptographique) en utilisant une image de fond (celle ci ou une autre de votre choix).

Cette fonction permet essentiellement d'insérer du texte (variable) sur un fond (constant).

N'oubliez pas de tester votre programme et d'inclure des exemples dans votre archive.

3.2. Intégration de la stéganographie et signature

Choisissez :

et écrivez une fonction principale qui prend en argument :

et génère le diplôme.

Cette fonction utilisera bien entendu ce que vous avez fait dans les questions précédentes...

N'oubliez pas de tester votre programme et d'inclure des exemples dans votre archive.

Voici une représentation des bits différents entre le diplôme que je génère et l'image vierge.

Comme vous pouvez le constater, 3 informations (dont une assez grosse) sont cachées dans le diplôme...

Écrivez une fonction qui permet d'extraire l'information cachée dans un diplôme.

Décrivez une manière de vérifier la signature.

N'oubliez pas de tester votre programme et d'inclure des exemples dans votre archive.

Si la signature est visible, la vérification de signature doit pouvoir être faite par l'utilisateur. Dans ce cas, vous devez soit fournir un programme spécifique, soit décrire comme faire la vérification en utilisant des outils existants.

4. Pour aller plus loin

Voici quelques idées pour améliorer vos diplômes.

Validation en ligne

ajout d'un site de validation des diplômes hébergé par NIHCAMCURT. Cela peut se faire en entrant un code ou une empreinte (qu'il faut alors ajouter sur le diplôme) ou avec le nom de l'étudiant.

Une manière simple simple pour faire un prototype en Python est d'utiliser bottle.

QR-code

ajout d'un QR-code contenant un lien vers un site de validation (cf. idée précédente).

La bibliothèque python-qrcode permet par exemple de créer des QR-codes en Python...

Horodatage certifié

Ajout d'une estampille certifiée permettant une vérification, par un tiers de confiance, de la validité du diplome ainsi que de la date de délivrance.

Pour ceci, il faut créer une "requête d'horodatage" (RFC 3161) que l'on envoie à un serveur d'horodatage (https://www.freetsa.org/ par exemple). Le serveur nous renvoie une réponse qui permet de vérifier la date d'enregistrement de la requête.

???

etc.