Compare commits

..

13 Commits

Author SHA1 Message Date
7a632ea129 tp3 2026-03-22 16:13:22 +01:00
3e183fbb1e tp3 2026-03-22 16:11:02 +01:00
7ba5098daa td3 2026-03-19 15:12:58 +01:00
c2c8b09dcf oups 2026-03-16 10:24:12 +01:00
126e99113f ajout tp2 2026-03-16 08:23:15 +01:00
5f84465e1f td2 2026-03-13 08:33:57 +01:00
c8287319b5 avec tux 2026-03-09 10:50:16 +01:00
e41e39e1c3 oups 2026-03-09 10:46:48 +01:00
8c44c653b5 ajout exo 2026-03-09 08:59:23 +01:00
bda797f631 ajout exo 2026-03-09 08:58:09 +01:00
b9aa998ba7 ajout exo 2026-03-09 08:56:20 +01:00
1fea0c18cf typo 2026-03-04 10:54:27 +01:00
5e03240950 typo 2026-03-04 10:52:51 +01:00
22 changed files with 966 additions and 7 deletions

View File

@@ -5,7 +5,16 @@ Cryptographie - Outils et algorithmes
[Cours crypto](cours/crypto.pdf) [Cours crypto](cours/crypto.pdf)
#### Semaine 1 #### Semaine 1
- cm : [Chiffrements par bloc, algorithmes à clefs symétriques](cours/crypto.pdf). - cm : [LFSR, Chiffrements par bloc, algorithmes à clefs symétriques](cours/crypto.pdf).
- td : [Généralités, chiffrements par flot](td/td1.pdf) - td : [Généralités, chiffrements par flot](td/td1.pdf)
- tp : [lfsr, xtea, hachages](tp/tp1) - tp : [Chiffrement ECB, lfsr, xtea](tp/tp1)
#### Semaine 2
- cm : [Algorithmes à clefs symétriques, Hachages](cours/crypto.pdf).
- td : [Chiffrements symétriques par blocs et modes](td/td2.pdf)
- tp : [Substitution-Permutation-Network](tp/tp2)
#### Semaine 3
- cm : [Algorithmes à clefs publiques, signatures](cours/crypto.pdf).
- td : [Hachages, Mac, signatures](td/td3.pdf)
- tp : [Openssl](tp/tp3)

BIN
cours/crypto_new.pdf Normal file

Binary file not shown.

BIN
td/td2.pdf Normal file

Binary file not shown.

BIN
td/td3.pdf Normal file

Binary file not shown.

View File

@@ -3,7 +3,7 @@
Lobjectif de cet exercice est de chiffrer une image en ligne de commande à Lobjectif de cet exercice est de chiffrer une image en ligne de commande à
laide des outils fournis par la librairie openssl. laide des outils fournis par la librairie openssl.
1. Prenez une image de votre choix et convertissez la dans le format ppm à laide de la commande 1. Prenez ~~une image de votre choix~~ l'image de [tux](https://fr.wikipedia.org/wiki/Tux#/media/Fichier:Tux.svg) et convertissez la dans le format ppm à laide de la commande
`convert`. `convert`.
2. Avec la commande `head`, mettez les 3 premières lignes de votre fichier ppm dans un fichier 2. Avec la commande `head`, mettez les 3 premières lignes de votre fichier ppm dans un fichier
@@ -25,17 +25,183 @@ le bit $b_0$ est remplacé par un bit, calculé par une fonction linéaire $f$.
Vous disposez d'un [fichier](src/ex1/file.crypt) crypté avec un lfsr, en faisant Vous disposez d'un [fichier](src/ex2/file.crypt) crypté avec un lfsr, en faisant
un XOR de chacun des octets avec les valeurs successives du registre. L'état un XOR de chacun des octets avec les valeurs successives du registre. L'état
initial du registre était `0xa7`, et la fonction utilisée initial du registre était `0xa7`, et la fonction utilisée
\[
f(b_7,b_6,b_5,b_4,b_3,b_2,b_1,b_0) = b_7\oplus b_6\oplus b_5\oplus b_4\oplus b_3\oplus b_1 $$ f(b_7,b_6,b_5,b_4,b_3,b_2,b_1,b_0) = b_7\oplus b_6\oplus b_5\oplus b_4\oplus b_3\oplus b_1 $$
\]
Retrouver le fichier initial. Retrouver le fichier initial.
Vous pouvez utiliser la fonction interne `__builtin_parity` de `gcc`. Vous pouvez utiliser la fonction interne `__builtin_parity` de `gcc`.
## EX3 (si vous avez tout fini)
eXtended Tiny Encryption Algorithm est un algorithme de chiffrement symétrique par
bloc. les algorithmes de chiffrement sysmétrique par bloc crypte/decrypte des
**blocs** entiers, en utilisant la même clé secrète (symétrique). XTEA est un
exemple simple de tels algorithmes (DES, AES, Blowfish) facile à implanter. La
plupart de ces algorithmes utilise ce que l\'on appelle un réseau de Feistel.
##### Réseau de Feistel
Désignons par $K$ la clé (un mot binaire). On décompose le bloc à
crypter en 2 moitiés $(L_0,R_0)$ On lui applique une
transformation de la forme :
$$
(L_0,R_0) \rightarrow (L_1,R_1)
\, où \,
\left\{\begin{matrix} L_1 & = & R_0 \\
R_1 & = & L_0 + f(R_0,K)
\end{matrix}\right.
$$
- La loi $+$ doit simplement être "réversible" (une loi de
groupe). Dans la pratique, il s'agit souvent d'un xor, mais pour
TEA, il s\'agit de l'addition binaire.
- La fonction $f$ n'a pas besoin d'être inversible pour que la
transformation précédente soit réversible.
Pourquoi ? Comment fait-on ?
- Le chiffrement consiste alors à itérer la transformation (appelée
round) un certain nombre de fois.
<div align="center">
<img src="./img/feistel.png">
</div>
##### XTEA
XTEA (cf cours) crypte des blocs de 8 octets, en utilisant une clé de 16 octets.
Un cycle (2 rounds, itéré 32 fois) de XTEA est donné par le réseau
suivant :
<div align="center">
<img src="./img/xtea.png">
</div>
En vert, il s'agit de l'addition binaire sur 32 bits, en rouge le xor.
- la clé est décomposée 4 sous-clés $K[0],K[1],K[2],K[3]$.
- chaque round utilise un multiple de $\delta = ( \sqrt{5} - 1 ) * 2^{31}$ pour rendre les rounds non symétriques.
Voici un exemple de code correspondant :
```c
void encrypt(uint32_t v[2], uint32_t const key[4])
{
unsigned int i;
uint32_t v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9;
for (i=0; i < 32; i++) {
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
}
v[0]=v0; v[1]=v1;
}
```
##### Padding (bourrage)
Lorsque l'on cherche à crypter un fichier, sa taille n'est pas
toujours un multiple de la longueur des blocs chiffrés par
l'algortihme. Il existe différentes techniques dites de padding. Nous
utiliserons celle-ci :
- Si le dernier bloc à chiffer du fichier n'est pas entier, on écrit
dans son dernier octet le nombre d'octets manquants. Les octets
précédents peuvent être zéroifiés, ou remplis aléatoirement.
- Si le dernier bloc est entier, on rajoute tout un bloc pour qu'il
n'y est pas d'ambiguité.
Voici un exemple avec des blocs de taille 8 octets. Le fichier en entrée
est
```
ascii : hello word!
hex : 68 65 6c 6c 6f 20 77 6f 72 6c 64 21
```
Le dernier bloc est
```
ascii : ord!
hex : 72 6c 64 21 00 00 00 04
```
On ajoute des zéros (ou des octets aléatoires), et le dernier est le
nombre d'octets ajoutés (ici, 4). Si le dernier bloc est complet, on
rajoute tout un bloc.
```
hex : 00 00 00 00 00 00 00 00 08
```
##### Votre travail
1. Ecrire une fonction qui decrypte un bloc.
2. Ecrire une commande **xtea** qui permet de (dé)chiffrer un fichier.
```bash
xtea -e|-d filekey file1 file2
```
- `filekey` est le fichier ou est stocké la clé. Vous pouvez en
générer en utilisant le pseudo fichier `/dev/urandom`, et la
commande `dd`.
- l'option `-e` crypte. `file1` est alors le fichier à crypter,
`file2` le fichier crypté.
- l'option `-d` decrypte. `file1` est alors le fichier crypté, `file2`
le fichier decrypté.
3. Testez avec cette [clé](./src/ex2/key1.k), et ce [fichier
crypté](./src/ex2/fichier.crypt) sur une architecture little-endian.
4. Écrire une version de tea en mode CBC :
```bash
xtea_cbc -e|-d iv filekey file1 file2
```
`iv` est le vecteur d'initialisation (8 octets) donné sur la ligne de commande.
**Rappel** : en mode CBC, le bloc à chiffrer subit un XOR avec le chiffré du bloc précédent. Le vecteur d'initialisation sert
pour le premier bloc.
## Ex4: une fonction de hachage cryptographique avec XTEA
Une fonction de hachage cryptographique permet de "résumer" un
fichier, message en calculant une empreinte. Une telle fonction,
mathématiquement, peut-être formalisée par
$$
\begin{matrix}
\{0,1\}^{*} & \rightarrow & \{0,1\}^n \\
m &\rightarrow & f(m) \end{matrix}
$$
$n$ est la taille de l'empreinte. Elle vaut 128 par exemple pour MD5 et SHA-1.
Grâce à XTEA, on va construire une telle fonction pour avec $n=64$.
Voici le principe.
- Le message ou fichier est décomposé en bloc de 24 octets (on bourrera
le dernier bloc suivant le pricincipe déjà vu en ajoutant des octets
avec la valeur du nombre d'octets ajoutés).
- Chaque bloc est vu comme un bloc suivi d'une clé de XTEA $x,k$
(bloc $x$ de 8 octets, clé $k$ de 16 octets). On calcule
$hash = xtea(x,k) \oplus x$.
- On combine le hash du bloc courant avec le hash du bloc précédent à
l'aide d'un xor. Le hash finale est l'empreinte.
##### Votre travail
1. Implantez le fonction prédente. Testez-là. Vérifiez que pour un message
"assez proche", l'empreinte est "vraiment" différente.

Binary file not shown.

1
tp/tp1/src/ex3/key1.k Normal file
View File

@@ -0,0 +1 @@
÷Nà {q2*:¬¨œÇmfU#© `í±Å?&Q3

11
tp/tp1/src/ex3/xtea.c Normal file
View File

@@ -0,0 +1,11 @@
void encrypt(uint32_t v[2], uint32_t const key[4])
{
unsigned int i;
uint32_t v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9;
for (i=0; i < 32; i++) {
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
}
v[0]=v0; v[1]=v1;
}

95
tp/tp2/README.md Normal file
View File

@@ -0,0 +1,95 @@
# TP2
> Dans ce tp, on implémente un algorithme de chiffrement par Blocs basé
> sur un réseau de permutation-substitution (SPN), en mode ECB.
### SPN
<div align="center">
<img src="./img/spn.png">
</div>
Ces algorithmes utilisent en entrée une clé, et applique à chaque bloc
plusieurs tours constitués de boîtes de substitutions (S-Box) et de
boîtes de permutations (P-Box).
- Une **S-Box** substitue à un ensemble de bits un autre ensembe de
bits (transormation bijective).
- Une **P-Box** est une permutation de bits. Elle prend la sortie
d'une S-Box, permutte les bits, et les transmet à une S-box au tour
d'après.
- A chaque tour, on combine le bloc avec la clé (ici un xor).
#### implantation
- la taille de bloc est 8 bits,
- le bloc est découpé en 2 sous-blocs de 4 bits chacun,
- la taille de la clef est 24 bits,
- la clef est décomposée en 3 sous-clefs de 8 bits chacun,
- le nombre de tours est égale à 2,
- les substitutions et les permutations sont les mêmes à chaque tour.
Remarques
On représentera dans le programme une substitution par un tableau
d'entiers (unsigned char) de taille 16.
```c
unsigned char s[]={14,3,2,10,12,11,15,9,0,4,7,13,1,8,6,5}
```
Ainsi, le bloc binaire 0011, qui vaut 3, sera remplacé par 1010 car `s[3]=10`
On représentera une permutation par un tableau d'entiers (`unisgned char`) de taille 16.
```
unsigned char perm[8]={5,0,4,6,7,1,2,3};
```
Ainsi, le bit de poids faible (rang 0) est placé au rang 5.
#### Votre travail
1. Ecrivez les fonctions suivantes, qui implantent le spn décrit ci-dessus.
```c
#ifndef _SPN_H
#define _SPN_H
unsigned char do_perm(unsigned char w,unsigned char perm[16]);
unsigned char do_subst(unsigned char w,unsigned char subst[16]);
unsigned char encrypt(
unsigned short w,
unsigned int key,
unsigned char perm[8],
unsigned char subst[16]
);
unsigned char decrypt(
unsigned short w,
unsigned int key,
unsigned char perm[8],
unsigned char subst[16]
);
#endif
```
2. Ecrivez des programmes spn-encrypt-file.c , spn-decrypt-file.c qui
implantent le SPN décrit ci-dessus. Les deux prennent sur la ligne de
commande :
- "nom fichier codé" et "nom fichier décodé "
- la clef
La permutation et la substitution seront codées en dur dans les programmes.
Testez vos programmes sur un exemple à vous.
3. Passez vos deux programmes en mode CBC.

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
tp/tp2/img/spn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

17
tp/tp2/src/Makefile Normal file
View File

@@ -0,0 +1,17 @@
all : spn-encrypt-file spn-decrypt-file
spn-encrypt-file.o : spn-encrypt-file.c
gcc -c spn-encrypt-file.c
spn-decrypt-file.o : spn-decrypt-file.c
gcc -c spn-decrypt-file.c
./lib/spn.o:./lib/spn.c
gcc -c ./lib/spn.c -o ./lib/spn.o
spn-encrypt-file : ./lib/spn.o spn-encrypt-file.o
gcc -o spn-encrypt-file ./lib/spn.o spn-encrypt-file.o
spn-decrypt-file : ./lib/spn.o spn-decrypt-file.o
gcc -o spn-decrypt-file ./lib/spn.o spn-decrypt-file.o

66
tp/tp2/src/lib/spn.c Normal file
View File

@@ -0,0 +1,66 @@
#include "spn.h"
void calc_inv_perm(unsigned char perm[8],unsigned char inv_perm[8])
{
// TODO
}
void calc_inv_subst(unsigned char subst[16],unsigned char inv_subst[16])
{
// TODO
}
unsigned char do_perm(unsigned char w,unsigned char perm[8])
{
unsigned char pw = 0; // permuted byte
int i;
unsigned char mask = 0x1;
unsigned char bit;
unsigned char place;
for(i=0;i<8;i++){
bit=w&mask;
place=perm[i];
pw |= bit<<place;
w>>=1;
}
return pw;
}
unsigned char do_subst(unsigned char w,unsigned char subst[16])
{
unsigned char sw=0;
// TODO
return sw;
}
unsigned char encrypt(
unsigned char w,
unsigned int key,
unsigned char perm[8],
unsigned char subst[16])
{
unsigned char k0=key&0xff;
unsigned char k1=(key>>8)&0xff;
unsigned char k2=(key>>16)&0xff;
// TODO
return w;
}
unsigned char decrypt(
unsigned char w,
unsigned int key,
unsigned char perm[8],
unsigned char subst[16])
{
unsigned char k0=key&0xff;
unsigned char k1=(key>>8)&0xff;
unsigned char k2=(key>>16)&0xff;
// TODO
}

24
tp/tp2/src/lib/spn.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef _SPN_H
#define _SPN_H
void calc_inv_perm(unsigned char perm[8],unsigned char inv_perm[8]);
void calc_inv_subst(unsigned char subst[16],unsigned char inv_subst[16]);
unsigned char do_perm(unsigned char w,unsigned char perm[8]);
unsigned char do_subst(unsigned char w,unsigned char subst[16]);
unsigned char encrypt(
unsigned char w,
unsigned int key,
unsigned char perm[8],
unsigned char subst[16]
);
unsigned char decrypt(
unsigned char w,
unsigned int key,
unsigned char perm[8],
unsigned char subst[16]
);
#endif

View File

@@ -0,0 +1,65 @@
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include "./lib/spn.h"
void randomize (unsigned char arr[], int n)
{
unsigned char tmp;
for (int i = n - 1; i > 0; i--)
{
// Pick a random index from 0 to i
int j = rand() % (i + 1);
// Swap arr[i] with the element
// at random index
// swap(&arr[i], &arr[j]);
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
int main(int argc, char *argv[])
{
int fd_in,fd_out;
unsigned int key;
unsigned char perm[8] = {0,1,2,3,4,5,6,7};
unsigned char subst[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
unsigned char inv_perm[8];
unsigned char inv_subst[16];
unsigned char buf;
assert(argc == 4);
srand(0);
randomize(perm,8);
randomize(subst,16);
calc_inv_perm(perm,inv_perm);
calc_inv_subst(subst,inv_subst);
fd_in = open(argv[1],O_RDONLY);
fd_out = open(argv[2],O_WRONLY|O_TRUNC|O_CREAT,0600);
key = (unsigned int)strtol(argv[3],NULL,0);
while(1){
ssize_t nb = read(fd_in, &buf, 1);
if (nb <=0)
break;
buf = decrypt(buf, key, inv_perm, inv_subst);
write(fd_out, &buf, 1);
}
close(fd_in);
close(fd_out);
return 0;
}

View File

@@ -0,0 +1,58 @@
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include "./lib/spn.h"
void randomize (unsigned char arr[], int n)
{
unsigned char tmp;
for (int i = n - 1; i > 0; i--)
{
// Pick a random index from 0 to i
int j = rand() % (i + 1);
// Swap arr[i] with the element
// at random index
// swap(&arr[i], &arr[j]);
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
int main(int argc, char *argv[])
{
int fd_in,fd_out;
unsigned int key;
unsigned char perm[8] = {0,1,2,3,4,5,6,7};
unsigned char subst[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
unsigned char buf;
assert(argc == 4);
srand(0);
randomize(perm,8);
randomize(subst,16);
fd_in = open(argv[1],O_RDONLY);
fd_out = open(argv[2],O_WRONLY|O_TRUNC|O_CREAT,0600);
key = (unsigned int)strtol(argv[3],NULL,0);
while(1){
ssize_t nb = read(fd_in, &buf, 1);
if (nb <=0)
break;
buf = encrypt(buf, key, perm, subst);
write(fd_out, &buf, 1);
}
close(fd_in);
close(fd_out);
return 0;
}

BIN
tp/tp3/M1.ps.gz Normal file

Binary file not shown.

BIN
tp/tp3/M2.ps.gz Normal file

Binary file not shown.

447
tp/tp3/README.md Normal file
View File

@@ -0,0 +1,447 @@
# TP4
> Dans ce tp, on utilise la boîte à outils **openssl** pour :
>
> - Chiffrage/déchiffrage (symétriques et à clés publiques).
> - Hashage.
> - Signature.
> - Création/utilisation de certificats.
### OpenSSL
<details><summary>Openssl</summary>
<div>
Vous pouvez utiliser les fonctionnalités suivantes :
```bash
openssl genrsa -out fichier_rsa.priv size
```
génére la clé privé RSA de taille size. les valeurs possible pour size
sont : 512, 1024, etc.
```bash
openssl rsa -in fichier_rsa.priv -des3 -out fichier.pem
```
chiffre la clef privé RSA avec l'algorithme DES3. Vous pouvez utiliser DES, 3DES, IDEA,etc.
```bash
openssl rsa -in fichier_rsa.priv -pubout -out fichier_rsa.pub
```
stocke la partie publique dans un fichier à part (création de de la clé
publique associée à la clef privée dans le fichier fichier.pem).
```bash
openssl enc -algo -in claire.txt -out chiffre.enc
```
pour le chiffrement de claire.txt avec l'algorithme spécifié (`openssl enc --help` pour avoir la liste des possibilités ou bien openssl
list-cipher-commands) dans un fichier chiffre.enc.
```bash
openssl enc -algo -in chiffre -d -out claire
```
pour le déchiffrement.
```bash
openssl dgst -algo -out sortie entrée
```
pour hacher un fichier. L'option -algo est le choix de l'algorithme de
hachage (sha, sha1, dss1, md2,md4, md5, ripemd160).
```bash
openssl rand -out clé.key nombre_bits
```
pour générer un nombre aléatoire de taille nombre_bits (utiliser
l'option -base 64 pour la lisibilité).
```bash
openssl aes-256-cbc -in claire.txt -out chiffre.enc -e -k clé.key
```
pour chiffrer un fichier avec l'AES.
```bash
openssl rsautl -encrypt -inkey rsa.pub -in clair.txt -out chiffre.enc
```
chiffrer fichier.txt avec la RSA en utilisant la clef publique rsa.pub.
```bash
openssl rsautl -decrypt -inkey rsa.priv -in chiffre.enc -out fihcier.txt
```
pour déchiffrer le fichier fic.dec.
```bash
openssl rsautl -sign -inkey ras.priv -in fichier.txt -out fic.sig
```
pour générer une signature.
```bash
openssl rsautl -verify -pubin -inkey rsa.pub -in fic.sig
```
pour vérifier une signature.
</div>
</details>
### Chiffrage symétrique
#### Avec mot de passe
La liste des algorithme de chiffrement symétrique est donnée par la
commande
```bash
openssl enc -ciphers
```
Pour chiffrer le fichier toto avec le système Blowfish en mode CBC, avec
une clé générée par mot de passe, le chiffré étant stocké dans le
fichier toto.chiffre , on utilise la commande :
openssl enc -bf-cbc -in toto -out toto.chiffre
Pour déchiffrer le même message, on utilise la commande :
openssl enc -bf-cbc -d -in toto.chiffre -out toto.dechiffre
**Exercice 1**
- Chiffrer et déchiffrer un fichier de votre choix. Vérifier avec la
commande `diff`.
- Comment expliquer la différence de taille du fichier et du fichier
chiffré ?
- Que se passe-t-il si le mot de passe est invalide ?
- Ajouter l'option `-iter` et `-salt` ? à quoi cela sert-il ?
**Exercice 2**
Le cryptogramme [cryptogramme](./cryptogramme) a été chiffré avec AES en
mode CBC, la clé de 128 bits ayant été obtenue par mot de passe. Sachant
le codage en base 64 du mot de passe est `VHN1bmFtaQo=`, déchiffrez le
cryptogramme.
#### Avec clé explicite (mode CBC)
Pour chiffrer le fichier toto avec une clé explicite, il faut utiliser
les options -K (ou -kfile) et -iv
- `-K` ( K majuscule) suivi de la clé exprimée en hexadécimal ;
- `-iv` ( iv en minuscules) suivi du vecteur d'initialisation exprimé
en hexadécimal.
L'exemple qui suit montre la commande pour chiffrer toto avec Blowfish
en mode CBC avec un vecteur d'initialisation de 64 bits, et une clé de
128 bits :
openssl enc -bf-cbc -in toto -out toto.chiffre \
-iv 0123456789ABCDEF \
-K 0123456789ABCDEF0123456789ABCDEF
**Exercice 3**
Générez une clé pour aes-256, ainsi qu'un vecteur d'initialisation
(128 bits). Chiffrez et déchiffrez (AES 256 en mode CBC) le fichier
clair correspondant au cryptogramme de la question précédente.
### Chiffrage à clé publique
On peut générer des clés RSA avec la commande
openssl genrsa -out keyfile size
**Exercice 4**
Générez une clé RSA sur 2048 bits dans le fichier key.pem. Que donne
`cat key.pem.`
openssl rsa -in keyfile -text -noout
permet de visualiser vos clés
**Exercice 5**
- Exportez la partie publique de votre clé dans key.pub. Regardez le
fichier.
- Chiffrez la clé privée avec idea et un mot de passe. Regardez ce que
contient le fichier.
```bash
openssl rsa -in maCle.pem -idea -out maCle.pem
```
- Chiffrez "un petit fichier". Quelle est la taille du fichier
chiffré ? Déchiffrez-le.
- Que se passe-t-il pour un gros fichier ? pourquoi ?
- Chiffrez un message avec l'option `-oaep`, et recommencer, en vérifiant que le chiffré
change.
**Exercice 6**
Envoyez votre clé publique à un camarade. Celui-ci vous enverra la sienne.
Générer un petit fichier texte et envoyez-le à votre voisin chiffré avec
sa clef publique. Lui vous enverra un fichier chiffré avec sa clef.
Renvoyez-lui le message qu'il vous a envoyé mais en clair.
**Exercice 7**
Toujours en binome : A génére une clef AES 256 qu'il chiffre avec la
clef publique RSA de B et il lui envoye le chiffré. A partir de là, B
récupère la clef (en clair), et il chiffre un gros fichier avec l'AES et
la clef AES. Il envoie le gros fichier chiffré à A qui doit le
déchiffré.
### Hachage et mots de passe
Pour calculer un hachage, utiliez la commande
openssl dgst -algo -out hash fichier
**Exercice 8**
1. Visitez les possibilités de la commande prime dOPENSSL.
2. Testez la primalité dun nombre donné : en plus de la réponse, constatez que l'écho de ce nombre
a lieu en hexadécimal.
3. Testez la primalité dun nombre passé directement en hexadécimal.
4. (facultatif) Ecrivez un petit shell-script UNIX de façon à faire afficher les nombres premiers d'un
intervalle donné (utilisez seq ou autre).
**Exercice 9**
1. À l'aide de la commande dgst, obtenir dans bash.hash, le hachage du
fichier exécutable `/usr/bin/bash`, en choisissant SHA256 (Secure
Hash Algorithm) comme algorithme de hashage. Refaire pour obtenir la
version binaire du hash dans le fichier executable.hash.bin.
Comparer la taille de `/usr/bin/bash`, de executable.hash et de
executable.hash.bin. Quelle est la longueur du hash en nombre de
bits ? On recommence avec un fichier court oof. Quelle est la
longueur du hash en nombre de bits ?
2. Changer un seul **bit** dans oof. Comment change le hash ?
3. On recommence avec MD5 (Digest Message) comme algorithme de hashage.
Quelle est la longueur des hashs en nombre de bits.
4. Récupérez les fichiers [fichier1](./M1.ps.gz) et
[fichier2](./M2.ps.gz). Décompressez-les, et regardez leur contenu.
5. Calculer leur empreinte MD5 avec `openssl`. Conclusion ?
6. Même question avec SHA-1 et SHA256.
7. S'il s'agit tout simplement de calculer des hashs, on peut utiliser
directement certaines commandes, sans passer par openssl. Par
exemple les commandes md5sum ou shasum. C'est le cas, par exemple,
lorsqu'on télécharge des packages dont on veut vérifier l'intégrité
de la copie (à condition bien sûr que le site officiel de l'éditeur
du package publie le hash du package).
**Exercice 10**
Vous vous retrouvez en possession du hachage MD5 d'un mot de passe que
vous voulez casser.
dde2790ce930e3d425305c36afd4e69c
Ecrivez un programme force brute qui teste tous les mots d'un
dictionnaire. Pour calculer le hachage MD5 d'une chaîne, utilisez la
fonction MD5 de openssl (-lcrypto à la compilation)
```c
#include <openssl/md5.h>
unsigned char *MD5(const unsigned char *d, unsigned long n,
unsigned char *md);
```
Testez avec le dictionnaire [cracklib-small](./cracklib-small.gz)
**Exercice 11**
Vous avez réussi à récupérer le fichier `/etc/shadow` d'un serveur avec
la ligne suivante
toto:$6$oAwY6QyT$WALN/YdWiU16lh19DqFHgLYYj77Grn3L88L8vX8IkgXQJyxH1r4L9/2zjY1fdM81Sx/cv821MXfPHbP.nvR2W.:16680:0:99999:7:::
Retrouvez le mot de passe du compte toto en procédant comme à
l'exercice précédent (utliser la fonction `crypt`)
```c
#include <crypt.h>
char *crypt(const char *key, const char *salt);
```
### Signature
Pour signer un "document", on calcule d'abord une empreinte de ce
document. La commande **dgst** permet de le faire.
openssl dgst -algo -out hash fichier
Signer un document revient à signer son empreinte. Pour cela, on utilise
l'option `-sign` de la commande **rsautl**.
openssl rsautl -sign -in hash -inkey cle -out signature
et pour vérifier
openssl rsautl -verify -in signature -pubin -inkey cle -out hash
**Exercice 12**
Le fichier [signatures.tar.gz](./signatures.tar.gz) contient deux
fichiers accompagnés d'une signature, ainsi que la clé publique de la
clé RSA ayant produit la signature. De ces deux fichiers, lequels a bien
été signé.
**Exercice 13**
Reprenez le binôme de la partie RSA. Envoyez à votre binôme le fichier
/etc/passwd et une signature, qui la vérifiera.
### Certificats
#### Création d'une autorité de certification (permettant de signer les demandes de certificats)
Vous allez jouer le role d'une autorité de certification.
Par défaut, OpenSSL utilise le fichier de configuration
```
/etc/ssl/openssl.cnf
```
pour la génération des certificats. Pour utiliser un fichier de
configuration personnalisé, il suffit d'ajouter l'argument "-config
{fichier_de_configuration_personnalisé}" à la commande openssl.
Avant de pouvoir générer un certificat , il faut obligatoirement générer
une clé RSA ou DSA. Générez une clé RSA `mykey.pem` pour l'autorité de
certification chiffrée avec idea.
Pour générer ses propres certificats, sans passer par une autorité de
certification externe :
openssl req -new -x509 -key mykey.pem -out ca.crt -days 1095
On indique pour le paramètre `-out` le nom de l'autorité de
certification à générer puis la durée de validité en jour avec le
paramètre `-days` Cette autorité de certification permettra de signer
les futures demandes de certificats auto-signés. Cette génération est à
faire une seule fois. Le Common Name à indiquer ne doit correspondre à
aucun nom de domaine ayant besoin d'un certificat. Cette autorité de
certification peut-être mis à disposition du public afin d'être intégré
dans les différents navigateurs comme étant une autorité de
certification reconnue.
#### Création d'une requête de certificat
Vous allez jouer le role de quelqu'un qui veut obtenir un certificat
pour sa clé RSA. Générez une clé RSA dans mykey.pem.
**Exercice 14**
Générez une requête de demande de certificat pour votre clé.
openssl req -new -key maCle.pem -out maRequete.pem
Consulez cette requête avec
openssl req -in maRequete.pem -text -noout
**Exercice 15**
Expliquez les différents éléments contenus dans cette requête. La clé
privée du sujet y figure-t-elle ?
#### Génération du certificat final
**Exercice 16**
A l'aide de la requête de certificat, générez un certificat pour votre
clé publique. Vous jouez donc le role ici de l'authorité de
certification.
openssl x509 -req -in maRequete.pem -out moncertif.pem -CA ca.crt -CAkey mykey.pem -CAcreateserial -CAserial ca.srl -days 90
Affichez ce que contient le certificat.
L'option `-CAcreateserial` est à utiliser seulement la première fois.
Ceci va générer un identifiant (ca.srl). Lors des prochaines
certification (pour renouvellement ou pour d'autres domaines)
l'identifiant, contenu dans le fichier ca.srl, sera incrémenté à
l'aide de l'option -CAserial ca.srl
Pour vérifier la validité d'un certificat, on peut utiliser la commande
verify :
openssl verify -CAfile ca.crt moncertif.pem
**Exercice 17**
Vérifier le certificat généré.
#### ncat avec SSL/TLS
On va utiliser ncat qui supporte SSL/TLS.
1. Avec tcp, échangez un fichier entre un client et un serveur ncat.
Vérifier avec tcpdump que le fichier passe **en clair** !.
2. Refaire la question précédente en utilisant SSL/TLS.
- Le serveur a maintenant besoin du certificat, et de la clé privé
correspondante (option `--ssl-cert` et `--ssl-key`)
- Le client doit aussi se connecter avec l'option `--ssl`.
- Le contenu du "fichier" échangé passe-t-il encore "en clair"
?
3. Que se passe-t-il coté client si vous rajoutez l'option
`--ssl-verify` ?
ncat --ssl-verify --ssl localhost port
4. Avec l'option `--ssl-trustfile`, dites à ncat de faire confiance à
l'autorité de certification qui a signé le certificat du serveur.
5. Connectez-vous au serveur ncat en utilisant votre browser. Pour
cela, faites un fichier `rep.http` qui contient une réponse http qui
sera renvoyée au navigateur. Par exemple
```html
HTTP/1.1 200 OK
<html>
<head>
<title>TP</title>
</head>
<body>
<h1>TEST</h1>
</body>
</html>
```
Le serveur renvoie systématiquement la même réponse :
ncat -l 8080 < rep.http
Vérifiez depuis votre navigateur.
6. On veut cette fois-ci se connecter à notre serveur ncat en https. On
utilise localhost comme nom.
7. Testez depuis votre navigateur. Que se passe-t-il ? Dites au
navigateur que vous faites confiance à l'autorité qui a signé le
certificat du serveur (comment ?)
8. Malgré tout, cela ne suffit pas. Le navigateur devrait vous réclamer
l'extension `subject Alternative Names` qui permet d'associer
emails, ip, noms, etc. En l'occurence, il faut associer le nom
localhost au certificat.
En tant qu'autorité de certification, recréez le certificat du
serveur en ajoutant localhost comme nom associé au certificat.
openssl x509 -req -in maRequete.pem -out moncertif.pem -CA ca.crt -CAkey mykey.pem -CAcreateserial -CAserial ca.srl -days 90 -extfile x509.cnf
le fichier x509.cnf
subjectAltName = DNS:localhost
Retestez.

BIN
tp/tp3/cracklib-small.gz Normal file

Binary file not shown.

BIN
tp/tp3/cryptogramme Normal file

Binary file not shown.

BIN
tp/tp3/signatures.tar.gz Normal file

Binary file not shown.