# PGP / GPG

# <i class="fa fa-user-secret" aria-hidden="true"></i>


## PGP

* Chiffrement asymétrique
* Phil Zimmermann
  * 1991
  * munition / cryptowar
* PGP abandonné
* GPG GnuPG sous GPL devient est le standard


# Gérer son envrionnement GPG


## gpgenv

* Simplifie la gestion des clés en créant des environnements temporaires
  * Permet de repartir de 0 simplement

<pre><code class="hljs bash" style="font-size: 30px">$ wget http://m4z3.me/gpgenv -O /tmp/gpgenv
$ source  /tmp/gpgenv
gpg --help
</code></pre>


## gpgenv

```bash
$ gpgenv create
new GNUPGHOME=/tmp/gnupg-Lw4Ck
```

* Crée un environnement (env) vierge localisé dans /tmp/gnupg-Lw4Ck.

```bash
$ gpgenv cd
```

* permet de se positionner dans le nouveau répertoire


#### gpgenv

```bash
$ gpgenv backup ~/Bureau/batman.tgz
```

* permet de sauvegarder son env dans un archive

```bash
$ gpgenv restore ~/Bureau/batman.tgz
Restored backup in /tmp/gnupg-ZuXYw
To activate it, use
    gpgenv use /tmp/gnupg-ZuXYw
```

* permet de restaurer un env à partir d'une archive

```bash
$ gpgenv use /tmp/gnupg-ZuXYw && gpgenv cd
```

* permet d'utiliser l'env restauré et de se positionner dans le répertoire associé


# Gérer ses clés GPG


## Création d’une clé PGP

* Création de la paire de clés de l’utilisateur
  * un « certificat » avec
    * la clé publique
      * signée avec la clé privée
    * identité de l’utilisateur


### Création d’une clé PGP maître

```bash
$ gpg --full-gen-key # or --gen-key
gpg (GnuPG) 2.1.11; Copyright (C) 2016 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Sélectionnez le type de clés désiré :
   (1) RSA et RSA (par défaut)
   (2) DSA et Elgamal
   (3) DSA (signature seule)
   (4) RSA (signature seule)
Quel est votre choix ? 1
```


### Création d’une clé PGP maître

* Choisir une taille de clé maximale
* Choisir une durée de vie infinie
  * elle doit être valide pour être utilisée
  * plus la durée de vie est nogue
    * plus on récolte de signature
* Saisir son identité
* Choisir un mot de passe fort


### Lister les clés

```bash
$ gpg --list-keys
pub   rsa4096/3E5AC6A0 2018-01-09 [SC]
uid        [  ultime ] Batman (clés à usage professionnel) <batman@batcave.com>
sub   rsa4096/31C5E7B9 2018-01-09 [E]
sub   rsa4096/DD6A21D4 2018-01-09 [S]

```

* liste toutes les clés de l'environnement
<small>
* 3E5AC6A0, batman@batcave.com sont 2 ids de la clé public
* 31C5E7B9 et DD6A21D4 sont les ids de la clé de chiffrement et de signature
</small>

```bash
$ gpg --list-private-keys
```

* liste toutes les clés privées de l'environnement
  * dont on a le mot de passe


### Fonctions des clés

| Constant          | Character |
|-------------------|-----------|
| PUBKEY_USAGE_SIG  |    S      |
| PUBKEY_USAGE_CERT |    C      |
| PUBKEY_USAGE_ENC  |    E      |
| PUBKEY_USAGE_AUTH |    A      |

Authentication

### Exporter une clé GPG

```bash
$ gpg --export --armor batman@batcave.com > batman.pub.asc
$ gpg --export --armor 3E5AC6A0 > batman.pub.asc
$ gpg --export --armor DD6A21D4 > batman.pub.asc
```
* exportent le même certificat (celui de la clé maître)
* ASCII-armor encrypted or signed output

```bash
gpg --export-secret-keys --armor \
    batman@batcave.com > batman.asc
```

* exporte la clé privée
  * le mot de passe est nécessaire


### Importer une clé

```bash
$ gpg --import batman.asc
```

* s'il s'agit d'une clé privée
  * le mot de passe sera demandé
  * les fonctionnalités de la clé seront ensuite utilisables

```bash
$ gpg --import robin.pub.asc
```

* s'il s'agit d'un certificat
  * aucun mot de passe ne sera demandé
  * la clé pourra être utilisée pour chiffrer à destination du détenteur de la clé


#### Editer une clé / Durcir le hashage

```bash
$ gpg --edit-key batman@batcave.com
$ gpg> setpref SHA512 SHA384 SHA256 SHA224 \
       AES256 AES192 AES CAST5 ZLIB BZIP2 \
       ZIP Uncompressed
$ gpg> save
```
* il faut bien sauvegarder avant de quitter le mode édition


#### Editer une clé clé maître / Ajouter une identité

```bash
$ gpg --edit-key batman@batcave.com
$ gpg> adduid
Nom réel : Bruce Wayne
Adresse électronique : bruce.wayne@gmail.com
Commentaire : clé à usage personnel
Vous utilisez le jeu de caractères « utf-8 ».
Vous avez sélectionné cette identité :
    « Bruce Wayne (clé à usage personnel) <bruce.wayne@gmail.com> »

Changer le (N)om, le (C)ommentaire, l\'(A)dresse électronique
ou (O)ui/(Q)uitter ? O
$ gpg> save
```

* Toutes les identités sont liées dans le certificat
  * pour utiliser GPG en tant que Bruce Wayne il faudra générer une autre clé maître


#### Editer une clé clé maître / Ajouter une photo

```bash
$ gpg --edit-key batman@batcave.com
$ gpg> addphoto
$ gpg> save
```

* l'image doit être petite pour garder une taille de clé raisonnable
  * 240x288 is a good size to use


## Sous clé

* Permet de conserver sa clé maître déconnectée
  * Mais de pouvoir utiliser la foncationnalités de la sous clé
    * idéal pour gérer une clé par appareil (mobile, laptop, fix, ...)

* quel est l'intérêt d'une sous clé de chiffrement?
* quel est l'intérêt d'une sous clé de signature?


#### Editer une clé / Ajouter une sous clé

```bash
$ gpg --edit-key batman@batcave.com
$ gpg> addkey
Sélectionnez le type de clés désiré :
   (3) DSA (signature seule)
   (4) RSA (signature seule)
   (5) Elgamal (chiffrement seul)
   (6) RSA (chiffrement seul)
Quel est votre choix ? 4
```

* choisir la fonctionnalité
* choisir une durée de vie
* choisir un nouveau mot de passe fort

```bash
$ gpg> save
```


#### Voir la nouvelle sous clé

```bash
$ gpg --list-secret-keys
/tmp/gnupg-RL2R8/pubring.kbx
----------------------------
sec   rsa4096/3E5AC6A0 2018-01-09 [SC]
uid        [ inconnu ???] Batman (clés à usage professionnel) <batman@batcave.com>
ssb   rsa4096/31C5E7B9 2018-01-09 [E]
ssb   rsa4096/DD6A21D4 2018-01-09 [S]
```


#### Exporter une sous clé

L'enjeu est de rendre la clé maître inutilisable

```bash
$ gpg --export-secret-subkeys --armor DD6A21D4 batman@batcave.com > batman@batcave.com.mobile.private.subkey
```
* l'id de la sous clé doit être précisé sans quoi toutes les sous clés sont exportées
* --armor ne fonctionne pas

Autre stratégie

```bash
gpg --delete-secret-key batman@batcave.com
gpg --export-secret-keys --armor batman@batcave.com > batman.mobile.asc
```

* ici --armor fonctionne


#### Voir la nouvelle sous clé "nettoyée"

```bash
$ gpg --list-secret-keys
/tmp/gnupg-RL2R8/pubring.kbx
----------------------------
sec#  rsa4096/3E5AC6A0 2018-01-09 [SC]
uid        [ inconnue ???] Batman (clés à usage professionnel) <batman@batcave.com>
ssb   rsa4096/31C5E7B9 2018-01-09 [E]
ssb   rsa4096/DD6A21D4 2018-01-09 [S]
```

* '#' signifie que la clé maître est inutilisable \o/
  * --edit-key refusera de sauver les opérations


## Publication d'un certificat

Partout

* sur une page web
* sur une carte de visite
* en pièce jointe ou dans le corps d'un message


### Serveurs de clé PGP

* existent depuis que gpg existe
* [http://pgp.mit.edu/](http://pgp.mit.edu/) est un des plus populaires
  * informations synchrones entre tous les Serveurs
    * suppression quasi impossible
      * beaucoup de clés obsolètes (non révoquées et non maîtrisées)
  * n'importe qui peut publier des clés publiques pour n'importe quelle identité
    * aucune vérification


### Serveur de clé 2nd génération

* [PGP Global Directory](https://keyserver.pgp.com/vkd/GetWelcomeScreen.event)
  * vérification de la maîtrise du (des) mail(s) associé(s) au certificats à la création
  * confirmation d'existence de la clé envoyée au(x) mail(s) associé(s) au certificats à intervalles réguliers
* non synchronisés avec les serveurs 1<sup>ère</sup> génération


### Keybase.io

* [Keybase.io](https://keybase.io)
  * récent
  * basé sur PGP
  * 2 parties
    * publication de la clé publique
      * confirmation via différents réseaux sociaux
    * correspondance / partage chiffré
      * nécessite l'import de la clé privée :/


### Keybase.io ... the right way

![KeyBase - host private key](images/gpg/keybase1.png)

Une autre fois peut être ;)


### Keybase.io ... the right way

![KeyBase - prove you have the private key](images/gpg/keybase2.png)


### Keybase.io ... the right way

![KeyBase - prove you have the private key(2)](images/gpg/keybase3.png)

Hardocre mode \o/

#### et une sous clé dédiée?


## une clé PGP sur une carte de visite?

* [asc2qr](https://github.com/4bitfocus/asc-key-to-qr-code)
  * ne marche pas

* [Putting my pgp idl ink on printed business cards](https://security.stackexchange.com/questions/70501/putting-my-pgp-id-link-on-printed-business-cards)
  * [qrencode](ht1tps://doc.ubuntu-fr.org/qrcode)
    * just do it!


## Révocation

* secret ou clé perdu
* secret ou clé compromis
  * l'attaquant peut
    * écrire en se faisant passer pour le propriétaire des clés
      * signer en général
    * lire tout message (passé et avenir) chiffré avec la clé publique


## Révocation

* révoquer la clé en question
  * distribuer la clé révoquée à tout ceux qui l'utilisent
    * appelé aussi certificat de révocation


## Révocation de la clé maître

* Il faut anticiper
  * créer le certificat de révocation dés la création de la clé

<pre><code class="hljs DD6A21D4" style="font-size: 15px">$ gpg --output batman.revoke.asc --gen-revoke batman@batcave.com

sec  4096R/0DCD0D14 2017-09-04 Batman (clés à usage professionnel) <batman@batcave.com>

Faut-il créer un certificat de révocation pour cette clés ? (o/N) o
choisissez la cause de la révocation :
  0 = Aucune raison indiquée
  1 = La clés a été compromise
  2 = La clés a été remplacée
  3 = La clés n'est plus utilisée
  Q = Annuler
</code></pre>


## Révocation d'une sous clé

* créer un certificat de révocation
  * à tout moment avec la clé maître

<pre><code class="hljs bash" style="font-size: 18px">$ gpg --output batman.mobile.revoke.asc --gen-revoke batman@batcave.com</code></pre>


## Publication du certificat de révocation

<pre><code class="hljs bash" style="font-size: 18px">$ gpg --import batman.mobile.revoke.asc # ou batman.revoke.asc
$ gpg --keyserver pgp.mit.edu --send-keys 6382285E</code></pre>

* En cas de perte ou de compromission uniquement
  * sinon la clé est invalidée
* la clé de révocation est à garder en lieu sûr
  * mais à un autre endroit que la clé maître


# Utiliser ses clés GPG


#### Chiffrer

```bash
$ gpg  --encrypt --armor --output msg.gpg \
       --recipient robin@batcave.com msg
```

* La clé (publique) robin@batcave.com doit faire partie du trousseau
  * importation au préalable
  * --recipient permet de spécifier la clé publique à utiliser

#### Déchiffrer

```bash
$ gpg --decrypt msg.gpg
```

* Effectué avec la clé privée robin@batcave.com
  * nécessite le mot de passe de cette clé privée


## Signer

* La signature
  * certifie un document à date
  * utilise la clé privée de l'émetteur
    * non répudiation

```bash
$ gpg --output doc.sig --sign doc
$ gpg --output doc --decrypt doc.sig
gpg: Signature made Fri Jun  4 12:02:38 1999 CDT using DSA key ID BB7576AC
gpg: Good signature from "Alice (Judge) <alice@cyb.org>"
```

* doc.sig contient le document compressé (format binaire) et signé
  * pas pratique pour une ISO par exemple


## Signature en claire

```bash
$ gpg --clearsign doc
```

Evite la compression
* document suivi d'une signature ASCII
* --local-user permet de spécifier la clé privée à utiliser


## Signature en claire

```bash
gpg --output doc.sig --detach-sig doc
```

produit la signature du fichier sans le fichier

```bash
gpg --verify doc.sig doc
```

le fichier et la signature sont nécessaires pour vérifier l'intégrité et l'authentification


# Gérer son réseau de confiance


### Configurer un serveur de clef

Dans .gnupg/gpg.conf

```bash
keyserver pool.sks-keyservers.net
```

Ou directement dans la ligne de commande

<pre><code class="hljs bash" style="font-size: 18px">$ gpg --keyserver pgp.mit.edu --search-keys pascal.lafourcade@udamail.fr</code></pre>


### Garder son trousseau à jour

```bash
$ gpg --refresh-keys
```

Automatisable via cron

```bash
# mettre à jour mes clefs OpenPGP à chaque jour, à midi
0 12 * * * /usr/bin/gpg --refresh-keys > /dev/null 2>&1
```


### Importer un clé à partir d'un serveur de clé public

```bash
gpg --keyserver pgp.mit.edu --recv-key 0EBE8000
```


## Réseau de confiance

* Les signatures sont publiques
  * on sait qui (quelle clé) a signé la clé de qui
    * soit qui fait confiance à qui (à quelle clé)
  * 5.5 est le nombre de noeuds moyen entre 2 utilisateurs de PGP
    * une signature n'est pas symétrique

[sig2dot GPG/PGP Keyring Graph Generator](http://www.chaosreigns.com/code/sig2dot/)


## Réseau de confiance

Avant de signer une clé il faut vérifier qu'elle appartient bien à une personne physique
* il faut
  * échanger la clé ou l'empreinte de la clé physiquement
  * faut vérifier les papiers d'identité de la personne


## Fingerprint

*Empreinte de clé*

* 2 clés avec le même fingerprint sont identiques
* similarité vérifiable par un humain
  * permet de vérifier une clé publique

```bash
$ gpg --fingerprint robin@batcave.com
```

ou

<pre><code class="hljs bash" style="font-size: 18px">$  gpg --edit-key robin@batcave.com
gpg> fpr
pub  1024D/9E98BC16 1999-06-04 Blake (Executioner) <blake@cyb.org>
             Fingerprint: 268F 448F CCD7 AF34 183E  52D8 9BDE 1A08 9E98 BC16
</code></pre>


## Signature d’une clé

Une clé PGP peut avoir plusieurs signatures
* Alice fourni à Bob l’empreinte de sa clé publique
* Bob vérifie que l’empreinte correspond
* Bob signe la clé publique avec sa clé privée
* Bob envoie à Alice clé publique d'Alice signée
* Alice importe sa clé dans son trousseau
  * La clé existe déjà, seule la nouvelle signature est ajoutée

http://openpgp.vie-privee.org/gpg-intro-5.html


## Signer une clé publique

```bash
$  gpg --edit-key robin@batcave.com
gpg> sign
```

ou

```bash
$ gpg --sign-key robin@batcave.com
```

* en cas d'UIDs multiples on peut
  * signer tous les UIDs
  * ou choisir celles que l'on souhaite signer
* **lsign** permet de signer localement (non exportable)


## Propager la signature

* La clé un fois signée doit être renvoyée à son propriétaire
* Il est également possible de la publier directement sur un serveur de clé première génération
  * le propriétaire n'est alors plus maître des signatures de sa clé
    * ce n'est pas une bonne pratique


#### Lister les signatures

```bash
$ gpg --list-sigs robin@batcave.com
pub  1024D/CE63A2E7 2000-02-23 Benoit <benoit@parinux.org>
sig        5ED61FDA 2000-06-06  [User id not found]
sig        CE63A2E7 2000-02-23  Benoit <benoit@parinux.org>
sig        B4C5FE7F 2001-07-18  [User id not found]
sub  2048g/B5A97C83 2000-02-23
sig        CE63A2E7 2000-02-23  Benoit <benoit@parinux.org>
```

ou

```bash
$ gpg --list-sigs robin@batcave.com
gpg> sigs
```

* Sans id de clé ```gpg --list-sigs``` liste toutes les clés avec toutes leurs signatures
* Les clés non importées dans le trousseau apparaissent en **[User id not found]**


#### Vérifier les signatures

```bash
$ gpg --check-sigs robin@batcave.com
pub  1024D/CE63A2E7 2000-02-23 Benoit <benoit@parinux.org>
sig?       5ED61FDA 2000-06-06  
sig!       CE63A2E7 2000-02-23  Benoit <benoit@parinux.org>
sig!       B4C5FE7F 2001-07-18  Olivier Berger <oberger@april.org>
sub  2048g/B5A97C83 2000-02-23
sig!       CE63A2E7 2000-02-23  Benoit <benoit@parinux.org>
```

ou

```bash
$ gpg --list-sigs robin@batcave.com
gpg> check
```
* Sans id de clé ```gpg --check-sigs``` vérifie toutes les clés avec toutes leurs signatures
* **?** non importées dans le trousseau
* **!** clés publiques du trousseau


## Récupérer automatiquement les clés dans le trousseau

<pre><code class="hljs bash" style="font-size: 20px">#!/bin/sh
echo ""
echo "Mise à jour des clés GnuPG :"
echo ""
for i in $(/usr/bin/gpg --list-keys | grep '^pub' | cut -c 12-19); \
    do /usr/bin/gpg --keyserver pgp.mit.edu --recv-key $i; done
</code></pre>


#### [Utiliser la confiance pour valider les clés](https://www.gnupg.org/gph/en/manual/x334.html)

```bash$
gpg --list-sigs robin@batcave.com
gpg> trust
```

1. Don't know (unknown default trust level)
2. I do NOT trust (none)
3. I trust marginally (marginal)
4. I trust fully (full)


#### [Utiliser la confiance pour valider les clés](https://www.gnupg.org/gph/en/manual/x334.html)

* **--completes-needed**
  * nombre de signatures de confiance pleine nécessaires pour qu'une nouvelle clé soit de confiance
    * défaut 1
* **--marginals-needed**
  * nombre de signatures de confiance marginale nécessaires pour qu'une nouvelle clé soit de confiance
    * défaut 3


### [Enigmail](https://enigmail.net)

* Intégration de GPG à [Thunderbird](https://www.mozilla.org/fr/thunderbird/)
* UI pour la gestion des clés
* Attention à la verison de GPG utilisée


### [openKeyChain](https://www.openkeychain.org/)

* Gestionnaire de clés PGP pour android
* Open source ([F-Droid](https://f-droid.org/))


### [k9mail](https://k9mail.github.io/)

* Client mail  pour android
* Open source ([F-Droid](https://f-droid.org/))
* bonne intégrationavec [openKeyChain](https://www.openkeychain.org/)


### [openpgp.js](https://github.com/openpgpjs/openpgpjs)

* [OpenPGP.js Introduction](https://github.com/openpgpjs/openpgpjs/wiki/Introduction)
* [security of running openpgp.js in a browser with the private key in html5 locals](https://security.stackexchange.com/questions/38219/security-of-running-openpgp-js-in-a-browser-with-the-private-key-in-html5-locals)