Key derivation

Lors d'un session de transport on a souvent besoin de nombreuses clés, puisqu'il ne faut jamais répéter les clés. La Key derivation est un moyen de créer des clés à partir d'un mot de passe et de sel.

Son autre avantage est de permettre de créer des clé de taille donné et de permettre de rendre plus uniforme une distribution de mots de passe (par exemple les mots de passes issus d'un échange de clé par Diffie-Hellman).

Principe

La façon la plus simple, si on a un PRF sous la main est de :

Puis il suffit d'étier le process à chaque fois que l'in veut une clé avec : $F(\text{SK}, \text{iv} || i)$, où $\text{iv}$ un texte désignant le type de mot de passe concernée et $i$ un nombre comptant le nombre de mots de passe que l'application a demandé.

Nous allons montrer préciser le principe en explicitant le protocole PBKDF2 encore très utilisé aujourd'hui. On lui préférera tout de même argon2, plus complexe, pour de nouvelles applications.

❯ openssl kdf -keylen 32 -kdfopt digest:SHA256 -kdfopt pass:"password" -kdfopt salt:"" -kdfopt iter:2 PBKDF2
8B:C2:F9:16:7A:81:CD:CF:AD:12:35:CD:90:47:F1:13:62:71:C1:F9:78:FC:FC:B3:5E:22:DB:EA:FA:46:34:F6

DK = PBKDF2(HMAC, Password, Salt, c, n)

avec DK = T1 || T2 || ... || Tn

Les Ti sont de la taille de la sortie du hash.

Et sont générés par : Ti = U1 ⊕ ... ⊕ Uc avec :

On vot que l'itération des fonctions de hash permet d'uniformiser le hash.

TBD "une ligne"

Argon2

Argon2 est le gagnant d'une compétition visant à trouver le meilleur hash de mot de passes. Le principe est le même que pour PBKDF2 mais utilise une matrice plutôt qu'une liste. Il cherche à empêcher le compromis temps/mémoire utilisé pour trouve des hash en :

  1. utilisant le plus de mémoire possible : pour qu'il soit impossible de remplacer du temps par de la mémoire
  2. empêche de remplacer la mémoire par du temps en pénalisant fortement la diminution de mé,oire

TBD "une matrice"

❯ openssl kdf -keylen 50 -kdfopt pass:"password" -kdfopt salt:'des grains de sel' -kdfopt iter:3  ARGON2D
A6:0E:10:5D:A0:6A:63:85:8A:1A:63:25:8E:99:F2:7C:C6:00:F3:23:BE:09:F6:91:62:E5:FD:B6:5F:DA:CF:C0
echo -n "password" | argon2 "des grains de sel" -l 50
Type:           Argon2i
Iterations:     3
Memory:         4096 KiB
Parallelism:    1
Hash:           62ac773d564f583c593e6091c72eeb48766fc1d1e314afdce0bc175328e98afbca29a5078035152cdac35d2720d9cc6cb4e3
Encoded:        $argon2i$v=19$m=4096,t=3,p=1$ZGVzIGdyYWlucyBkZSBzZWw$Yqx3PVZPWDxZPmCRxy7rSHZvwdHjFK/c4LwXUyjpivvKKaUHgDUVLNrDXScg2cxstOM
0.014 seconds
Verification ok

Attention, tous les paramètres sont importants. Trouver le même hash avec openssl et argon2 semble impossible.

Usage

Trois usages courant :