OpenPGP
RSA peut encrypter un nombre plus petit que $n$. On pourrait décomposer un message plus gros en paquets de $T$ bits avec $2^T < n$ mais ce n'est quasi-jamais fait car le codage/décodage est algorithmiquement long.
On utilise alors une technique mixte, issue de PGP, pour cela.
Supposons qu'Alice veut envoyer un message $m$ à Bob. Il faut de :
- l'authentification : Alice chiffre le hash de $m$ avec sa clé privée
- la confidentialité :
- une clé $k$ est générée puis chiffrée avec la clé publique de Bob
- le message $m$ est compressé puis chiffré avec la clé $k$ (avec un chiffre symétrique)
Alice envoie à Bob :
- la signature électronique de son message (le hash de $m$ chiffré avec sa clé privée)
- la clé $k$ chiffrée avec la clé publique de Bob
- le message compressé puis chiffré avec la clé $k$
Bob peut alors :
- retrouver la clé de chiffrement $k$ en utilisant sa clé privée
- déchiffrer le message avec la clé $k$, puis le décompresser
- vérifier que le message vient bien d'Alice en comparant :
- le hash du message
- le déchiffrement de la signature avec la clé publique d'Alice.
Avec openSSL
Nous allons faire les meme étapes que le protocole openPGP avec la suite d'outils de chiffrement donné par openSSL pour bien séparer les différentes étapes. Si vous voulez utiliser pleinement le protocole openPGP, utilisez cependant plutôt un outil dédié gomme Gnupg, ci-après.
Placez vous dans un dossier où vous pourrez placer tous les fichiers nécessaires
On utilise la version 3 d'openSSL :
openssl version
Clés du chiffrement asymétrique
openssl genkpey -help
On commence par générer un couple de clés publique/privée avec RSA :
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
Cette commande va produire un fichier private_key.pem
au format PEM. Ce fichier va faire office de clé privée mais il contient bien le couple des clés publique et privée :
openssl rsa -in private_key.pem -text
Extrayons la clé publique du fichier private_key.pem
et stockons là dans le fichier public_key.pem
:
openssl rsa -pubout -in private_key.pem -out public_key.pem
La taille du fichier public_key.pem
ne contient que la clé publique (il est bien plus petit que le fichier private_key.pem
)
openssl rsa -pubin -in public_key.pem -text
Pour bien faire, changez les droits du fichier private_key.pem
pour qu'il ne soit lisible que par vous.
solution
solution
chmod go-r private_key.pem
On peut distribuer notre clé publique pour pouvoir recevoir des messages privés.
Envoyez par mail votre clé publique à la personne avec laquelle vous voulez échanger un message privé. Vous devrez chacun avoir la clé publique de l'autres :
- vous devrez avoir la clé publique de l'autre personne pour chiffrer la clé symétrique
- l'autre personne devra avoir votre clé publique pour vérifier la signature du message chiffré
Clé du chiffrement symétrique
Créons une clé de 32B = 256b pour être utilisée par chacha20.
openssl rand -hex -out symmetric_key 32
Le fichier symmetric_key.pem
contient la clé.
Vérifiez que la taille du fichier symmetric_key.pem
est bien compatible avec une clé de 256b.
solution
solution
wc -c symmetric_key
Donne 65. C'est cohérent :
- 1 caractère pour le retour à la ligne final
- un byte est codée sur 2 digit hexadécimaux. Il y a donc $(65-1) / 2 = 32B$
- un Byte vaut 8b, on a bien $32 \cdot 8 = 256b$
Chiffrement symétrique
On écrit un petit message à envoyer :
echo "Un coucou chiffré." > msg.txt
On commence par compresser ce fichier (on utilise ici zip, mais vous pouvez utiliser ce que vous voulez) :
zip -u msg.txt.zip msg.txt
OpenSSL permet le chiffrement symétrique avec plein d'algorithmes différents :
openssl enc -ciphers
Chiffrons avec chacha20 :
openssl enc -p -chacha20 -in msg.txt.zip -out msg.txt.zip.encrypted -kfile symmetric_key -pbkdf2
On utilise ici un passphrase qui va dériver les paramètres de chacha : une clé de chiffrement et un IV. On a utilisé ici des clés explicites. On peut aussi passer via des passphrases dont sont dérivées les clés et IV :
openssl enc -p -chacha20 -in msg.txt.zip -out msg.txt.zip.encrypted -K $(openssl rand -hex -out symmetric_key 32) -iv $(openssl rand -hex 16)
TBD faire avec K et IV
Chiffrement asymétrique de la clé symétrique
TBD faire avec sign then encrypt. COmme ça on cache l'expéditeur puis zip les trois fichiers à envoyer.
Signature
On signe un hash. OpenSSL propose plein de fonction de hash différente :
openssl dgst -list
On va utiliser sha256 pour signer le message chiffré avec notre clé privée :
openssl dgst -sha256 -sign private_key.pem -out msg.txt.zip.encrypted.sign.sha256 msg.txt.zip.encrypted
Chiffrement de la clé
Chiffrons la clé symétrique avec la clé publique de notre interlocuteur :
openssl pkeyutl -encrypt -in symmetric_key -pubin -inkey public_key.pem -out symmetric_key.encrypted
Envoi du message
Il faut envoyer :
- le message chiffré :
msg.txt.zip.encrypted
- la signature du message chiffré :
msg.txt.zip.encrypted.sign.sha256
- la clé symétrique chiffrée avec la clé publique de l'interlocuteur :
symmetric_key.encrypted
Déchiffrement
Vous devez avoir :
- la clé publique de l'envoyeur
- votre clé privée
Vérification de la signature
openssl dgst -verify public_key.pem -signature msg.txt.zip.encrypted.sign.sha256 msg.txt.zip.encrypted
Si tout s'est bien passé vous devriez voir Verified OK
comme réponse (sinons vous auriez eu Verification failure
comme réponse).
Déchiffrement de la clé symétrique
openssl pkeyutl -decrypt -inkey private_key.pem -in symmetric_key.encrypted -out symmetric_key
Déchiffrement du message
openssl enc -d -p -chacha20 -in msg.txt.zip.encrypted -kfile symmetric_key -pbkdf2 -out msg.txt.zip
Dézippage du message
unzip msg.txt.zip
Et normalement, vous devriez avoir le fichier initial !
Avec gnupg
Le logiciel gnuPG permet de rendre plus pratique les diverses opérations faites précédemment. Il permet également un partage de clés publique via un réseau de confiance. Une clé publique va être signée par d'autres personnes, ce qui permet de la valider : si une clé est signée par une personne que vous connaissez, vous aurez confiance en sa véracité.
Ne signez les clés publique que des personnes que vous connaissez.
On utilise la version 2.4.3 de GnuPG :
$ gpg --version
gpg (GnuPG) 2.4.3
libgcrypt 1.10.2
Copyright (C) 2023 g10 Code GmbH
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Home: /Users/fbrucker/.gnupg
Algorithmes pris en charge :
Clef publique : RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Chiffrement : IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256,
TWOFISH, CAMELLIA128, CAMELLIA192, CAMELLIA256
Hachage : SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression : Non compressé, ZIP, ZLIB, BZIP2
On voit que chacha20 n'est pas pas pris en compte comme algorithme de chiffrage, ce qui est dommage. Nous utiliserons donc les algorithmes par défaut, qui sont :
RSA
comme gestionnaire de clés asymétriqueAES256
comme algorithme de chiffrementSHA512
comme algorithme de hash
Création de clés
gpg --full-generate-key
RSA and RSA
: pour le chiffrement de la clé symétrique et la signature- taille de clé 3072
- expire d'ici 10 jours.
- tapez une passphrase qui protège votre clé. Ne l'oubliez pas
Vous pouvez voir votre clé :
gpg --list-keys
Nous allons tout de suite créer un fichier de révocation de la clé, au cas où vous perdriez votre passphrase ou que clé privée soit compromise.
gpg --output revoke-gpg.asc --gen-revoke <id clé>
Où <id clé>
est un des composant de votre clé qui l'identifie de façon unique parmi vos clés. Le nom de l'adresse mail mail par exemple.
Votre clé publique est :
gpg --armor --export <id clé>
Et si vous voulez la sauver dans un fichier pub.gpg
:
gpg --armor --output pub.gpg --export <id clé>
Préférences de clés
gpg --edit-key <id clé>
Vous vous retrouvez devant un prompt. Vous pouvez taper help
pour l'aide. Tapez setpref
et regardez vos préférences. Vous devriez y voir les différents algorithmes utilisés :
gpg> setpref
Définir la liste de préférences en :
Chiffrement : AES256, AES192, AES, 3DES
AEAD: OCB
Hachage : SHA512, SHA384, SHA256, SHA224, SHA1
Compression : ZLIB, BZIP2, ZIP, Non compressé
Fonctionnalités : MDC, AEAD, Serveur de clefs sans modification
Faut-il vraiment mettre à jour les préférences ? (o/N) n
Vous pouvez ensuite taper quit
pour quitter l'interface.
gpg> quit
Gestion des clés
Pour pouvoir envoyer des messages à quelqu'un, il vous faut avoir sa clé publique.
Envoyez votre clé publique à votre correspondant, et récupérez la sienne.
gpg --import public-key.pgp
Vous pouvez ensuite voir que la clé a bien été ajoutée à votre trousseau de clés :
gpg --list-keys
Vous pouvez, si vous le désirez, signer sa clé :
gpg> sign
Utilisation
Chiffrement :
gpg --output msg.txt.gpg --encrypt --recipient <recipient id> msg.txt
Chiffrement et signature du message :
gpg --output msg.txt.gpg --encrypt --sign --recipient <recipient id> msg.txt
Uniquement signature d'un message en clair
gpg --output msg.txt.sign --clearsign msg.txt
Déchiffrement :
gpg --output msg.txt --decrypt msg.txt.gpg
Gestion des clés GPG
TBD : faire mieux et plus clair.
utilitaire
serveur de clés
TBD Permet d'utiliser des clés stockées dans un serveur de clé https://www.gnupg.org/gph/en/manual.html#AEN464
- le faire.
- se signer mutuellement les clés.
Fichiers de configurations
Dans le dossier ~/.gnupg
.