You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

522 lines
17 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{
"cells": [
{
"cell_type": "markdown",
"id": "338e936b-4606-4210-9a52-912dd0863021",
"metadata": {},
"source": [
"# Exercice 1 (Collisions *). \n",
"Lobjectif des fonctions de hachages naïves dans cet exercice est de vous\n",
"permettre de trouver des collisions facilement grâce à un petit programme et un peu de réflexion.\n",
"## 1. Soient les hachés suivants par une certaine fonction de hachage H :\n",
"H(A) = 65 \n",
"H(B) = 66 \n",
"H(C) = 67 \n",
"H(Z) = 90 \n",
"H(a) = 97 \n",
"H(z) = 122 \n",
"H(AB) = 131 \n",
"H(ABC) = 198 \n",
"H(CB) = 133 \n",
"Quel est le calcul effectué par cette fonction de hachage H ? Trouvez (au moins) une pré-image\n",
"de 298 (qui a du sens ou pas).\n",
"## 2. Pour éviter les soucis des anagrammes, on modifie un peu la fonction de hachage et on\n",
"construit la fonction G suivante, qui produit les hachés suivants : \n",
"G(A) = 65 \n",
"G(B) = 66 \n",
"G(C) = 67 \n",
"G(D) = 68 \n",
"G(AB) = 197 \n",
"G(ABC) = 398 \n",
"G(ABCD) = 670 \n",
"G(BAC) = 397 \n",
"Trouvez le fonctionnement de cette nouvelle fonction de hachage G et deux prénoms dau plus\n",
"cinq lettres qui forment une collision. \n",
" \n",
"Les personnages célèbres suivants peuvent vous aider : \n",
"Federer, Hitchcock, Knuth, Obispo, Polo, Popeye, Murphy, Shannon, Smith, Turing, Turner,\n",
"Tyson, Wilde"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "ea4f90f3-36ca-4f12-af26-9c6847af7e53",
"metadata": {},
"outputs": [],
"source": [
"def H(nb):\n",
" if len(nb) != 1 :\n",
" return preImage(nb[0]) + preImage(nb[1:])\n",
" else :\n",
" return ord(nb)"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "c48d6f3c-fe28-4b3b-a9cb-8be2ec37573c",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"298\n"
]
}
],
"source": [
"print(H(\"HeG6\"))"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "1701ad6d-9684-48d5-abb5-127a3eba41f1",
"metadata": {},
"outputs": [],
"source": [
"def G(nb):\n",
" res = ord(nb[0])\n",
" for i in range(1, len(nb)) :\n",
" res = res + ord(nb[i]) * (i + 1)\n",
" return res"
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "7757972f-0c4d-417c-a110-1f3fb964b167",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"398\n",
"670\n"
]
}
],
"source": [
"print(G(\"ABC\"))\n",
"print(G(\"ABCD\"))"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "34b9e03c-f4ba-4bf2-8a3c-4147a7c0b17b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2950\n",
"4672\n",
"1630\n",
"2276\n",
"1600\n",
"2253\n",
"2347\n",
"3008\n",
"1600\n",
"2248\n",
"2289\n",
"1665\n",
"1526\n"
]
}
],
"source": [
"print(G(\"Federer\"))\n",
"print(G(\"Hitchcock\"))\n",
"print(G(\"Knuth\"))\n",
"print(G(\"Obispo\"))\n",
"print(G(\"Poloj\"))\n",
"print(G(\"Popeye\"))\n",
"print(G(\"Murphy\"))\n",
"print(G(\"Shannon\"))\n",
"print(G(\"Smith\"))\n",
"print(G(\"Turing\"))\n",
"print(G(\"Turner\"))\n",
"print(G(\"Tyson\"))\n",
"print(G(\"Wilde\"))"
]
},
{
"cell_type": "markdown",
"id": "dbef33be-4ac9-4d28-a229-10c596e40396",
"metadata": {},
"source": [
"## Exercice 2 (Adobe*). Voici un extrait (fictif) de la base de données Adobe qui a (réellement) fuité il y a maintenant quelques années.\n",
"| Login | Hint | Hash SHA-256 | \n",
"| --- | --- | --- |\n",
"| Bart | element 74 | 068be8be83f9bfafd1545d357fd3cd132f8c659effd11e635a698811b796c880 | \n",
"| Bob | numbers | 15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225 |\n",
"| Carlton | 1 to 9 | 15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225 |\n",
"| Homer | metal | 068be8be83f9bfafd1545d357fd3cd132f8c659effd11e635a698811b796c880 |\n",
"| John | nine | 15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225 |\n",
"| Lisa | mendeleiev 74 | 068be8be83f9bfafd1545d357fd3cd132f8c659effd11e635a698811b796c880 |\n",
"| March | hard rock | 068be8be83f9bfafd1545d357fd3cd132f8c659effd11e635a698811b796c880 |\n",
"| William | numbers - 0 | 15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225 |"
]
},
{
"cell_type": "markdown",
"id": "e802b941-181b-4132-b5cf-986070ee5e2e",
"metadata": {},
"source": [
"Dans un terminal, la commande ```echo -n password | shasum -a 256 ```ou la commande ```echo -n\n",
"password |openssl sha256``` génére le haché du mot password avec la fonction de hachage\n",
"SHA-256 : \n",
"5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8 \n",
"Le programme Python suivant calcule aussi le haché du mot password avec la fonction de hachage\n",
"SHA-2566. \n",
"``` python\n",
"1 import hashlib\n",
"2\n",
"3 mot=\"password\"\n",
"4 sha256=hashlib.sha256(mot.encode('utf-8')).hexdigest()\n",
"5\n",
"6 print(sha256)\n",
"```\n",
"Listing 1 Haslib pour SHA-256. \n",
"Trouvez les 2 mots de passe qui sont utilisés par ces utilisateurs dAdobe, prouver vos résulats."
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "a04d1367-b82a-4aa0-af10-cca7d841e691",
"metadata": {},
"outputs": [],
"source": [
"import hashlib"
]
},
{
"cell_type": "code",
"execution_count": 43,
"id": "ec73042d-5317-45c2-a26c-fd97c41778e4",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8\n"
]
}
],
"source": [
"mot=\"password\"\n",
"sha256=hashlib.sha256(mot.encode('utf-8')).hexdigest()\n",
"\n",
"print(sha256)"
]
},
{
"cell_type": "code",
"execution_count": 44,
"id": "8462a77d-9048-4b2f-afef-ce8944283dd0",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"068be8be83f9bfafd1545d357fd3cd132f8c659effd11e635a698811b796c880\n"
]
}
],
"source": [
"mot=\"tungsten\"\n",
"sha256=hashlib.sha256(mot.encode('utf-8')).hexdigest()\n",
"print(sha256)"
]
},
{
"cell_type": "code",
"execution_count": 45,
"id": "fc2c879b-769f-4fd0-9b6d-fd3f6495afba",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225\n"
]
}
],
"source": [
"mot=\"123456789\"\n",
"sha256=hashlib.sha256(mot.encode('utf-8')).hexdigest()\n",
"print(sha256)"
]
},
{
"cell_type": "markdown",
"id": "7f60c926-7860-4a5e-90a0-6bd2ac9817f3",
"metadata": {},
"source": [
"# Exercice 3 (Signature RSA naïve *).\n",
"Rappel du fonctionnement de la signature RSA naïve :\n",
"• Clé publique : pk = (e, n)\n",
"• Clé privée : sk = d\n",
"• Signature : σ de m avec sk vaut md mod n\n",
"• Vérification de sigma avec pk : tester que σ\n",
"e mod n est bien égal à m\n",
"## 1. Codez la fonction de signature de RSA. Pour calculer les puissances modulaires rapidement et efficacement, vous souhaiterez peut-être utiliser la commande pow(a,b,c).\n",
" \n",
"## 2. Avec pk = (e = 17, n = 3233) et d = 2753, signez 855. On ne vous demande pas de vérifier que les clés RSA sont correctes.\n",
" \n",
"## 3. Montrez quil est possible dobtenir une signature de 2197."
]
},
{
"cell_type": "code",
"execution_count": 73,
"id": "37ff643c-7849-4be8-944b-2927b483e54f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Signature de 855: 123\n",
"Signature de 2197: 2197 le message correspondant est 855*855 mod n\n"
]
}
],
"source": [
"def sign_rsa(message, sk, n):\n",
" return pow(message, sk, n)\n",
"\n",
"# Clé publique\n",
"pk = (17, 3233)\n",
"# Clé privée\n",
"sk = 2753\n",
"\n",
"# Signature du message 855\n",
"signature_855 = sign_rsa(855, sk, pk[1])\n",
"print(\"Signature de 855:\", signature_855)\n",
"\n",
"\n",
"signature_2197 = sign_rsa(855*855, sk, pk[1])\n",
"print(\"Signature de 2197:\", signature_2197, \"le message correspondant est 855*855 mod n\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0227b0b7-24a2-46bd-b9d6-ea8ba2173493",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "d842d4a6-103e-46a2-8c07-b3537b291a14",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "a03071a3-6fa8-4b97-a919-ec3f47b6873e",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "c642e70f-28ce-4d5e-89da-d91d97d243c8",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "76f680be-cdd5-4ce2-9b6e-86669768cbb2",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "ba67268a-e796-4783-899e-f635bb53e683",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "d1e9ca7a-6952-45ac-b615-e736bf4fc8fd",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "edde7a9b-4907-4418-ac9e-9be5761480f9",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"id": "09808691-4ef8-4097-bd9b-cf1285e93144",
"metadata": {},
"source": [
"# Exercice 4 (OpenSSL).\n",
"## Chiffrement Symétrique\n",
"### 1. Créez un fichier texte message.txt avec le message de votre choix. Utilisez la commande suivante pour chiffrer ce message avec openssl :\n",
"openssl enc -aes-256-cbc -pbkdf2 -in message.txt -out ciphersym.bin\n",
"### 2. Envoyez ce message chiffré à une autre personne avec le mot de passe. La personne peut alors déchiffrer le message avec la commande suivante :\n",
"openssl enc -d -aes-256-cbc -pbkdf2 -in ciphersym.bin -out plainsym.txt\n",
"## Génération de clefs RSA\n",
"### 1. Générez une paire de clef RSA de longueur 4096 avec la commande suivante :\n",
"openssl genrsa -aes256 -out rsakey.pem 4096\n",
"La passphrase doit faire entre 4 et 1023 caractères.\n",
"### 2. Extrayez la clé publique de rsakey.pem avec la commande suivante :\n",
"openssl rsa -in rsakey.pem -pubout -out public.pem\n",
"### 3. Les informations sur le module et les nombres premiers utilisés sont chiffrées avec AES-256 dans le fichier rsakey.pem. Utilisez la commande suivante pour trouver les éléments N, p, q, e et d de la clé RSA générée.\n",
"openssl rsa -in rsakey.pem -noout -text\n",
"### 4. Utilisez Python pour vérifier que les valeurs sont correctes.\n",
"## Chiffrement à clef publique\n",
"### 1. En utilisant la commande suivante, chiffrez le même message message.txt avec la clef RSA\n",
"que vous avez générée précédemment :\n",
"openssl pkeyutl -encrypt -in message.txt -pubin -inkey public.pem\n",
"-out cipherasym.bin\n",
"### 2. Comparez les deux chiffrés obtenus (symétrique et asymétrique) et leurs tailles.\n",
"### 3. Déchiffrez le chiffré cipherasym.bin avec la commande suivante :\n",
"openssl pkeyutl -decrypt -in cipherasym.bin -inkey rsakey.pem\n",
"-out plainasym.txt\n",
"### 4. Quelle est le nombre maximal de caractères que peut contenir le fichier message.txt ? Pour\n",
"info, un fichier .txt commence par un header (invisible) de 12 octets. Vous voudrez peut-être\n",
"vous aider dune commande du type python3 -c print(\"a\"*10) > message2.txt pour\n",
"vérifier vos hypothèses.\n",
"### 5. Envoyez votre clé publique à une autre personne et demandez-lui de vous envoyer un message\n",
"chiffré, puis déchiffrez-le avec votre clé privée.\n",
"## Signature\n",
"### 1. Pour signer un message, on utilise le chiffrement RSA, avec la commande suivante :\n",
"openssl pkeyutl -sign -in messageasigner.txt -inkey rsakey.pem\n",
"-out signedmessageasigner.bin\n",
"### 2. Quelle est le nombre maximal de caractères que peut contenir le fichier messageasigner.txt ?\n",
"### 3. Comment signer des messages plus gros ? La commande suivante peut vous aider :\n",
"openssl dgst -sha256 -binary message.txt > hmessage.dgst\n",
"### 4. Pour vérifier la validité dune signature il faut utiliser la commande suivante :\n",
"openssl pkeyutl -verify -in messageasigner.txt -pubin -inkey public.pem\n",
"-sigfile signedmessageasigner.bin"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d0e31cca-8a58-4b7b-95f5-260c4f5af117",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"id": "858de775-ce1e-4650-97b7-27e69c176687",
"metadata": {},
"source": [
"# Exercice 5 (Injection de faute sur la signature RSA CRT).\n",
"1. Choisissez un paramètre de sécurité k et générez des clés RSA. Vous voudrez peut-être utiliser\n",
"la fonction randprime de la bibliothèque sympy, la fonction randint de la bibliothèque\n",
"random et la fonction gcd de la bibliothèque math.\n",
"2. On rappelle que la signature RSA naïve dun message m consiste à calculer σ = md mod n,\n",
"où d est la clef secrète et n = p · q le module, tandis que la vérification de la signature σ dun\n",
"message m consiste à tester si σ\n",
"e mod n est égal à m.\n",
"Générez un message m au hasard, signez-le et vérifiez-en la signature.\n",
"3. Pour la signature RSA CRT (où RCT = Chinese Remainders Theorem), on commence par\n",
"précalculer en privé a = q · (q\n",
"1 mod p) et b = p · (p\n",
"1 mod q). Ensuite, la signature du\n",
"message m est s = a · s1 + b · s2, où s1 = md mod p et s2 = md mod q, et la vérification\n",
"de la signature s dun message m consiste à tester si s\n",
"e mod n est égal à m.\n",
"Calculez a et b, générez un message m au hasard, signez-le et vérifiez-en la signature.\n",
"4. La signature RSA CRT est vulnérable à une attaque par injection de faute, qui permet de\n",
"trouver un des deux facteurs premiers de n (et donc lautre, et donc la clef privée...). Pour\n",
"cela, lattaquant demande deux fois la signature dun même message m, et la deuxième fois, il\n",
"perturbe le calcul de s1. Il obtient ainsi une signature correcte s et une signature erronée s\n",
" du\n",
"message m. Or s et s\n",
" ont le même reste modulo q (cest s2) et des restes différents modulo\n",
"p (pour s cest s1 et pour s\n",
"\n",
"cest une valeur erronée), par conséquent, q divise s s\n",
"\n",
", mais\n",
"p ne le divise pas. Lattaquant calcule alors PGCD(s s\n",
"\n",
", n), qui vaut q. En effet, les seuls\n",
"diviseurs de n sont 1, p, q et n.\n",
"Générez une valeur erronée aléatoire pour s1, et calculez q."
]
},
{
"cell_type": "markdown",
"id": "85143f7e-6a12-473c-9fdf-8eec556f4a77",
"metadata": {},
"source": [
"# Exercice 6 (Algorithme de signature de Schnorr *).\n",
"À partir dun nombre premier p et dun générateur g publics, Alice se munit dune clef secrère sk\n",
"aléatoire (mais comprise entre 2 et p 1) et publie la clef publique associée pk = g\n",
"sk mod p. Elle\n",
"souhaite envoyer un message m authentifié à Bob. Le schéma de signature de Schnorr choisit un k\n",
"aléatoire entre 2 et p 1, puis calcule r = g\n",
"k mod p. Soit e = H(r ∥ m) mod p, où ∥ représente\n",
"la concatenation, et H une fonction de hachage. Soit s = k sk e mod (p-1) , alors la signature\n",
"est σ = (s, e). La vérification consiste à calculer rv = g\n",
"s\n",
"· p\n",
"e\n",
"k mod p, et à vérifier que H(rv ∥ m) est\n",
"égal à e.\n",
"1. Codez la fonction de génératiron de pk à partir de p, g et sk . Choisissez un paramètre de\n",
"sécurité et générez p et g, puis sk et pk . Vous voudrez peut-être utiliser des fonctions des\n",
"bibliothèques random et sympy.\n",
"2. Codez les fonctions de signature et de vérification. Vous voudrez peut-être utiliser la bibliothèque hashlib.\n",
"3. Signez le message m = 42 et vérifiez la signature."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.5"
}
},
"nbformat": 4,
"nbformat_minor": 5
}