Author: Sandra C.

Tutoriels

Comment chiffrer et déchiffrer un message

Le chiffrage/cryptage existe depuis des siècles, bien avant la naissance de l’informatique, il permet de protéger des informations et de communiquer des messages secrets. En lisant ce tutoriel, découvrez à votre tour des techniques antiques et modernes de chiffrement et de déchiffrement, qui vous permettront de comprendre comment sécuriser vos messages ou bien simplement à vous amuser avec vos amis

Quelques termes essentiels

Nous allons d’abord définir quelques mots de base qui apparaîtront au cours de ce tutoriel :

Cryptographie :  la cryptographie c’est l’ensemble des techniques de chiffrement, qui permettent de chiffrer un message. La cryptographie est principalement utilisée pour protéger un message considéré comme confidentiel.

Clé : Les clés de chiffrement sont des caractères ou séquences de caractères utilisés, avec un algorithme ou un processus mathématique, pour transformer des données en texte clair en un texte chiffré, ou un contraire transformer un texte chiffré en texte en clair.

Substitution : C’est une manière de chiffrer un message en remplaçant ses caractères par d’autres caractères. Ces caractères ne sont pas aléatoires mais sont définit à l’aide d’une clé ou d’une table de substitution.

Ensuite, il est important de comprendre les termes de chiffrement et de cryptage :

Le chiffrement consiste à transformer des informations lisibles, appelées texte en clair, en un format illisible, appelé texte chiffré, en utilisant une clé. Le cryptage est un synonyme, souvent utilisé pour désigner le chiffrement mais le terme le plus approprié et utilisé en cryptographie est celui de chiffrement. On parle de déchiffrement lorsque l’utilisateur dispose de la clé nécessaire pour retrouver le texte en clair. Et de décryptage lorsqu’on parvient à traduire des informations chiffrées en informations lisibles sans disposer de la clé (souvent via une attaque brute).

Les types de chiffrement

Il existe différents types de chiffrement, voici les deux principaux :

Symétrique : système de chiffrement qui utilise une seule clé pour chiffrer ET déchiffrer un texte. L’inconvénient est que si quelqu’un arrive à avoir la clé il peut lire tous les infos.

Asymétrique : système de chiffrement qui utilise deux clés différentes : une clé(public) pour chiffrer et une autre clé(privé) pour déchiffrer. Donc un message chiffré avec la clé publique ne peux être déchiffré qu’avec la clé privée correspondante, et inversement. L’inconvénient c’est que même si il est un peu plus sécurisé, ce système est beaucoup plus lent.

Le chiffre de César

Le code de César est une méthode de chiffrement antique, utilisé par Jules César pou faire parvenir ses messages secrets sans qu’il soit intercepté par les troupes ennemies. Le concept est très simple il suffit de décaler dans l’ordre alphabétique les lettres d’un mot.

Pour chiffrer avec le code de César je dois donc choisir un nombre de décalage, et l’appliquer à l’alphabet.

Voici un exemple schématisé avec un décalage de 3 :

Mais comment fait-on pour le déchiffrer ? Si on connaît la clé il suffit juste de compter dans l’autre sens mais c’est peu probable qu’on nous la donne. Pour la trouver ce n’est pas très compliqué, on repère les lettres les plus répétées, on suppose que c’est un E ou un A, et on compte jusqu’à la lettre correspondante sur le message chiffré.

Exemple : « OH FKLHQ » le H est répété deux fois je suppose que c’est un E, il y aurait donc un décalage de 3 : je compte à l’envers et j’obtiens : « le chien ». La clé utilisée :

clair : ABCDEFGHIJKLMNOPQRSTUVWXYZ
chiffré : DEFGHIJKLMNOPQRSTUVWXYZABC

On a ici de la chance, car cette méthode est compliqué lorsque nous avons peu de mots.

L’autre possibilité serait d’essayer tous les décalages possibles, ca peut nous paraître long (sauf si nous disposons du disque de césar), mais ca ne l’ai pas du tout pour un ordinateur, et c’est là le problème de ce code qui est bien trop simple à déchiffrer.

Voici une proposition de script Python :

Celui-ci fonctionne avec un décalage de 9 dans l’ordre alphabétique, mais tu peux bien sur le modifier par n’importe quel nombre (préférablement compris entre 1 et 26)

cryptage = {chr(65+i) : chr(65+(i+9)%26) for i in range(26)}
message = "message a modifier"
message_crypte = ""
for j in message:
    message_crypte = message_crypte + cryptage[j]
print(message_crypte)

Le chiffre de Vigenère

C’est un système de chiffrement par substitution du 16-ème siècle qui utilise une clé et un tableau à double entrée. Chaque lettre du texte à chiffrer est décalée selon la lettre correspondante de la clé, avec le tableau. Si tu te poses la question, la clé ne possède par forcement le même nombre de caractère que le mot à déchiffrer, si celle-ci est plus courte il faut simplement la répéter pour qu’elle soit assez longue.

Pour chiffrer avec la méthode de Vigenère il faut choisir une clé, puis il faut prendre la première lettre de notre mot à chiffrer et celui de notre clé dans chaque colonne, et récupérer la lettre qui se trouve à leur intersection.

Exemple : le mot de base commence par « s… » et la clé commence par « c… » : on regarde dans le tableau et la lettre au croisement de « c » et « s » est « u », le mot chiffré commence donc par « u ».

Comment le déchiffre t-on ? Lorsque nous avons un texte chiffrer avec la méthode de Vigenère nous sommes également en possession d’une clé. On se munie alors du tableau de Vigenère (voir ci dessous) et nous cherchons la lettre qui se trouve au croisement de la lettre du texte chiffré et de celle qui lui correspond dans la clé.

Exemple : le mot chiffré commence par « m… » et la clé commence par « c… » : on regarde dans le tableau et la lettre au croisement de « c » et « m » est « o », le mot déchiffré commence donc par « o ».

Le tableau de Vigenère

 ABCDEFGHIJKLMNOPQRSTUVWXYZ
AABCDEFGHIJKLMNOPQRSTUVWXYZ
BBCDEFGHIJKLMNOPQRSTUVWXYZA
CCDEFGHIJKLMNOPQRSTUVWXYZAB
DDEFGHIJKLMNOPQRSTUVWXYZABC
EEFGHIJKLMNOPQRSTUVWXYZABCD
FFGHIJKLMNOPQRSTUVWXYZABCDE
GGHIJKLMNOPQRSTUVWXYZABCDEF
HHIJKLMNOPQRSTUVWXYZABCDEFG
IIJKLMNOPQRSTUVWXYZABCDEFGH
JJKLMNOPQRSTUVWXYZABCDEFGHI
KKLMNOPQRSTUVWXYZABCDEFGHIJ
LLMNOPQRSTUVWXYZABCDEFGHIJK
MMNOPQRSTUVWXYZABCDEFGHIJKL
NNOPQRSTUVWXYZABCDEFGHIJKLM
OOPQRSTUVWXYZABCDEFGHIJKLMN
PPQRSTUVWXYZABCDEFGHIJKLMNO
QQRSTUVWXYZABCDEFGHIJKLMNOP
RRSTUVWXYZABCDEFGHIJKLMNOPQ
SSTUVWXYZABCDEFGHIJKLMNOPQR
TTUVWXYZABCDEFGHIJKLMNOPQRS
UUVWXYZABCDEFGHIJKLMNOPQRST
VVWXYZABCDEFGHIJKLMNOPQRSTU
WWXYZABCDEFGHIJKLMNOPQRSTUV
XXYZABCDEFGHIJKLMNOPQRSTUVW
YYZABCDEFGHIJKLMNOPQRSTUVWX
ZZABCDEFGHIJKLMNOPQRSTUVWXY

Le chiffrage par substitution

De nombreux chiffrements fonctionne par substitution mais cette méthode est « propre à elle-même ». En effet, les méthodes de chiffrage précédentes sont pas les plus sécurisés car elle offre peu de possibilités, alors que le chiffrage par substitution, lui, offre des milliards de possibilités le rendant presque impossible à déchiffrer.

Comme nous l’avons vu au début de cet article la substitution c’est remplacer des caractères par d’autres caractères. Ces caractères ne sont pas forcement des lettres, ils peuvent être des emojis ou bien des formes géométriques (la plupart des sociétés secrètes fonctionne avec la géométrie : code des templiers, franc maçon ou encore croix de lorraine).

Pour chiffrer un message avec cette méthode part d’une principe que le chiffrage par substitution est beaucoup plus libre et n’obéit pas à une règle précise, donc tu dois toi même créer une clé, en choisissant les caractères que tu veux utiliser et la manière dont tu les attribue

Créer des messages (presque) indécryptable

Voici quelques techniques qui peuvent rendre votre message encore plus compliqué a décrypter et qui rendra fou celui qui tente de le découvrir :

  • attribuer plusieurs caractères à une même lettre (ex : je remplace le « E » par les lettres « N », « S », et « I »)
  • retirer certaines lettres
  • retirer les espaces
  • ajouter des séquences/enchainements de lettres très peu probables
  • former des mots seulement lisibles en diagonale
  • faire des fautes volontaires

Comment décrypter n’importe quel message

Décrypter c’est parvenir à transformer un texte chiffré en texte clair sans la clé, il faut alors fonctionner par étapes pour arriver à la trouver. La technique que nous allons étudier se nomme la Markov Chain Monte Carlo (MCMC) et a été établi par un professeur de Stanford et ses élèves il y a quelques années

  • Premièrement il faut étudier la fréquence d’apparition d’un caractère (utilisé pour déchiffrer Enigma;) ; si on sait que le texte est français le caractère le plus utilisé sera probablement un E, ou un A. On peu par exemple classer les 5 caractères les plus utilisés et les remplacer par les 5 lettres les plus répétées en français

Voici un tableau du top 5 des lettres qui apparaissent le plus dans la langue française :

RangCaractèreNombre d’occurrencesPourcentage
1e115 024 20512.10%
2a67 563 6287.11%
3i62 672 9926.59%
4s61 882 7856.51%
5n60 728 1966.39%
  • Après cette analyse, on peut déjà proposer une clé (cela ne veut pas dire qu’elle doit être absolument correcte, tu peux donc classer certaine lettre qui ont la même fréquence un peu comme bon de semble car on s’en occupe après)
  • On applique cette clé et on voit si le message est plausible. Cette vérification est déjà possible à l’œil nu, car on repère les enchainements de lettres qui sont probables ou non (avoir un enchainement de ce type « wlm » est peu possible en français par exemple). Mais on va tout de même appliquer un facteur de plausibilité qui va nous permettre de calculer la probabilité que la clé que l’on propose soit valide. Il faut calculer la probabilité des enchainement, « DE » est beaucoup plus plausible que « XJ » son facteur est donc plus élevé.
  • On échange ensuite deux lettres et on recalcule le facteur de plausibilité, notre but est d’avoir un facteur de plausibilité le plus grand possible, avec des enchainements plus correctes. Pour cela il faut accepter les changements qui fonctionnent et ceux qui ne fonctionnent pour mieux progresser et trouver la bonne clé (algorithme de Metropolis).
  • Après de nombreuses permutations on peut normalement trouvé la bonne clé, soit le bon message !

Le chiffrement le plus sécurise : AES-256

Tu ne trouveras pas ici le moyen de chiffrer ou décrypter avec cette méthode mais il me semblait essentiel de l’évoquer.

L’AES-256 est un algorithme de cryptographie symétrique et sûrement le plus sécurisé du monde. Il fonctionne avec une clé de 256 bits (d’où son nom), et chiffre le message en 14 tours, c’est a dire qu’il chiffre le texte au cours de chacune des 14 étapes/tours, sur des blocs de 16 octets. Il est pratiquement incassable par n’importe quelle méthode de force brute, et est même parfois considéré comme résistant aux attaques quantiques (utilisation des principes de la mécanique quantique pour compromettre la sécurité des systèmes cryptographiques). C’est un moyen de chiffrement qui est utilisé dans les applications gouvernementales et militaires, aux Etats-Unis principalement, ou par les entreprises opérant dans des industries hautement réglementées.

Pour plus d’informations, je te propose d’aller lire cet article .

Petit jeu

Essaye maintenant d’identifier le chiffrement utilisé et de le déchiffrer ! Bonne chance 🎲

Message chiffré : DIYKH HA RSGLCWUZ

Clé : CRYPTOGRAPHIE

(solution : ISSUER SA UT OVARB)

Art

Le grand canyon

Pour ce premier projet en spécialité NSI, nous avons décidé de produire un paysage inspiré du Grand Canyon. Dans cet article, vous pourrait retrouver toutes les étapes pour créer cette image.

Le projet

Pour ce projet nous avons donc décidé de produire une image d’un paysage inspirée du Grand Canyon. Pour cela nous utilisons le module turtle, le module utilisé pour produire l’image ainsi que le module random. Nous avons également utilisé le script permettant d’exporter une image générée par turtle en .png que vous pouvez retrouver ici.

Au commencement

Nous nous sommes tout d’abord inspirés de l’image ci-dessous, et après en avoir réalisé un rapide croquis à la main nous avons commencé notre script : nous avons créé plusieurs fonctions pour chaque élément, que nous avons ensuite appelées dans un ordre précis à la fin du code. 

Structure du script

Pour la structure de notre script, nous avons choisi de réaliser seulement des fonctions (sol, soleil, cactus, montagnes…) et de les appeler à la fin dans un ordre respectif, en y mettant les coordonnées pour celles qui le demande, afin de construire notre image.

Le script étape par étape

Commençons par l’appel des modules et la mise en place de turtle.

from turtle import *
from random import randint

"""
Ce fichier est expliqué ici : https://nsi.xyz/py2png
Un autre tutoriel permet de commencer : https://nsi.xyz/tutoriels/decouvrir-le-module-turtle-de-python/
"""

try:
    from PIL import Image
    pillow_installed = True
except:
    print("Oops! - ModuleNotFoundError: No module named 'PIL' - RTFM :")
    print("https://nsi.xyz/py2png")
    pillow_installed = False
titre = "Paysage - construite avec turtle"
title(titre+" | Au lycée, la meilleure spécialité, c'est la spé NSI")
setup(1280, 720)
colormode(255)
speed(0)
hideturtle()

Ce code permet d’appeler les différents modules mais également de vérifier que l’utilisateur a bien installé le module PIL et dans le cas contraire un message d’erreur s’affichera et lui donnera un lien pour installer le module et tout ça sans que le script ne s’arrête.  Aprés vérification du bon fonctionnement du script, on met à jour le titre du projet ainsi que sa taille. Enfin on définit le type de couleurs utilisées (R,G,B), la vitesse de la tortue, et on la dissimule.

Commençons par la première fonction : le fond

def fond():
penup()
rciel = 0
gciel = 0
bciel = 0
hauteur = -360
goto(-642,-358)
pendown()
while hauteur != 360:
pencolor(round(189 + rciel), round(224 + gciel), round(254 + bciel))
forward(1280)
hauteur += 1
goto(-640, hauteur)
rciel += (-42/180)
gciel += (-7/45)
bciel += (-15/500)

Pour le fond on aurait pu utiliser une fonction qui crée directement un rectangle et qui le remplit avec fill_rect, or celui-ci aurait été uni alors que nous souhaitons observé un léger dégradé. Nous avons donc produit un script qui, en faisant avancé la tortue à partir d’un point de départ goto et qui ajoute la différence de chaque couleur (rouge, vert et bleu) entre la couleur de début du dégradé et la couleur de fin, produit un fond dégradé, ici de couleur bleue.

Deuxième, troisième et quatrième fonction : Les sols

def sol1():
	penup()
	goto(-640,-360)
	fillcolor(65, 72, 51)
	begin_fill()
	forward(1280)
	left(90)
	forward(175)
	left(90)
	forward(1280)
	left(90)
	forward(175)
	left(90)
	end_fill()

Pour réaliser un effet de profondeur nous avons réalisé un dégradé au niveau des sols en créant trois fonctions différentes sous la forme de la première fonction : sol1(). Pour réaliser le sol on a utilisé de nouveau goto qui permet de placer la tortue avant de la faire avancer pour remplir l’espace.

On répète donc cette fonction en changeant les coordonnées de goto et en éclaircissant la couleur.

def sol2():
	penup()
	goto(-640,-186)
	fillcolor(101, 109, 74)
	begin_fill()
	forward(1280)
	left(90)
	forward(50)
	left(90)
	forward(1280)
	left(90)
	forward(50)
	left(90)

def sol3():
	penup()
	goto(-640,-137)
	fillcolor(164, 172, 134)
	begin_fill()
	forward(1280)
	left(90)
	forward(50)
	left(90)
	forward(1280)
	left(90)
	forward(50)
	left(90)
	end_fill()

Ensuite on réalise les montagnes, pour cela on doit créer différentes fonctions, car aucune montagne n’a la même forme.

Montagne 1 :

def montagne1():
    #montagne derrière la première
    penup()
    goto(-560,-190)
    fillcolor(158, 78, 39)
    begin_fill()
    forward(250)
    left(120)
    forward(50)
    right(30)
    forward(160)
    left(90)
    forward(10)
    left(90)
    forward(50)
    right(90)
    forward(5)
    right(90)
    forward(80)
    left(90)
    forward(140)
    left(90)
    forward(40)
    right(90)
    forward(8)
    left(90)
    forward(120)
    right(42)
    forward(70)
    end_fill()

On utilise donc de nouveau goto pour faire déplacer notre tortue et faire en sorte qu’elle dessine a peu près la même forme de montagne que sur la photo. On remplit à l’aide de begin_fill() que l’on arrête à la fin avec end_fill().

On crée ensuite les autres montagnes en changeant la forme et en les éclaircissant légèrement pour créer un effet de profondeur.

Montagne 2 et 3 :

def montagne2():
    #montagne derrière la première
    penup()
    goto(340,-150)
    fillcolor(173, 94, 55)
    begin_fill()
    right(228)
    forward(210)
    left(120)
    forward(30)
    right(30)
    forward(130)
    left(90)
    forward(140)
    left(90)
    forward(9)
    right(80)
    forward(10)
    left(78)
    forward(120)
    right(40)
    forward(2)
    end_fill()
    
def montagne3():
    #montagne derrière la première
    penup()
    goto(-60,-100)
    fillcolor(201, 116, 75)
    begin_fill()
    left(132)
    forward(125)
    left(120)
    forward(50)
    right(30)
    forward(75)
    left(90)
    forward(15)
    right(45)
    forward(7)
    left(45)
    forward(25)
    left(45)
    forward(7)
    right(45)
    forward(26)
    left(90)
    forward(26)
    right(90)
    forward(5)
    right(90)
    forward(10)
    left(90)
    forward(5)
    left(90)
    forward(50)
    right(50)
    forward(5)
    end_fill()

Ensuite la fonction permettant de dessiner les cactus : On a d’abord attribué les coordonnées x et y à la fonction cactus, qui seront choisies lors de son appel,  déterminant alors l’emplacement du cactus sur l’écran, et permettant de l’appeler plusieurs fois a différent coordonnées. On définit ensuite la couleur, la taille et l’épaisseur du trait, on oriente la tortue vers le bas avec la fonction setheading()à 270, puis on commence à dessiner les bras et le tronc du cactus.

def cactus(x, y) :
    pencolor(56, 176, 0)
    pensize(10)
    penup()
    goto(x, y)
    pendown()
    setheading(270)
    forward(50)
    left(90)
    forward(30)
    left(90)
    forward(50)
    penup()
    goto(x + 16, y + 16)
    pendown()
    setheading(270)
    forward(125)

On réalise une autre fonction qui dessine un cactus comme le code précédent mais avec des dimensions différentes.

def cactus_petit(x, y) :
    pencolor(56, 176, 0)
    pensize(5)
    penup()
    goto(x, y)
    pendown()
    setheading(270)
    forward(25)
    left(90)
    forward(15)
    left(90)
    forward(25)
    penup()
    goto(x + 7, y + 7)
    pendown()
    setheading(270)
    forward(65)

Pour dessiner les virevoltants, que l’on peut retrouver dans le désert : on a tout d’abord attribue les coordonnées x et y (comme précédemment) à la fonction paille, pour l’appeler à différents endroits de l’image. Nous avons ensuite crée une boucle « for i in range » qui dessine des cercles beiges et qui incrémente 1 à chaque nouveau cercle dessiné, réalisant donc, à chaque répétition, des cercles de plus en plus grands.

def paille(x, y) :
    penup()
    goto(x,y)
    pendown()
    radius = 0
    for i in range(20) :
        color(166, 138, 100)
        pensize(1)
        circle(radius)
        radius += 1
       

Par la suite nous codons la fonction dessinant les nuages : On a (encore une fois) attribue les coordonnées x et y à la fonction nuage, pour l’appeler à différents endroits de l’image ; pour que les deux nuages soient tous les deux horizontaux, on utilise la fonction setheading() en l’orientant à 0 et on dessine ensuite 3 cercles blancs de différentes tailles, chacun d’eux avançant après avoir été dessiné.

def nuage(x, y):
    penup()
    goto(x, y)
    setheading(0)
    fillcolor(255, 255, 255)
    begin_fill()
    circle(25)
    forward(40)
    circle(35)
    forward(35)
    circle(18)
    end_fill()

Puis celle pour dessiner le soleil : on a tout simplement établit l’emplacement de celui-ci et fait un cercle de couleur jaune.

def soleil() :
    penup()
    goto(385,250)
    fillcolor(224, 161, 66)
    begin_fill()
    circle(30)
    end_fill()

Enfin, la fonction pour dessiner un oiseau simple en bâton : on a établit la couleur et l’épaisseur du trait, orienté la tortue avec la fonction setheading() à 290 pour qu’elle soit bien horizontale, puis fait une boucle qui trace un trait et qui tourne a gauche à deux reprises.

def oiseaux() :
    penup()
    pencolor(0, 0, 0)
    pensize(3)
    goto(395, 258)
    pendown()
    setheading(290)
    for i in range(2):
        left(50)
        forward(15)
       

Pour produire notre image finale, nous appelons toutes les fonctions (en ajoutant les coordonnées de certaines) :

#appel des fonctions        
fond(), sol1(), sol2(), sol3(), montagne1(), montagne2(), montagne3()  
cactus(-600,-150), cactus(500,-240)
cactus_petit(230, -100)
paille(100, -200), paille(-550, -300), paille(480, -330)
nuage(-480, 200), nuage(490, 180)
soleil()
oiseaux()

Résultat final

Télécharger en .py