Article de reference

Fédération de Hong Kong

HKDF est une fonction de dérivation de clé simple (KDF) basée sur le code d'authentification de message HMAC . Elle a été initialement proposée par ses auteurs comme élément de ...

HKDF est une fonction de dérivation de clé simple (KDF) basée sur le code d'authentification de message HMAC . Elle a été initialement proposée par ses auteurs comme élément de base dans divers protocoles et applications, ainsi que pour décourager la prolifération de multiples mécanismes KDF. L'approche principale suivie par HKDF est le paradigme « extraire-puis-étendre », où la KDF se compose logiquement de deux modules : la première étape prend le matériel de chiffrement d'entrée et en « extrait » une clé pseudo-aléatoire de longueur fixe, puis la deuxième étape « étend » cette clé en plusieurs clés pseudo-aléatoires supplémentaires (la sortie de la KDF).

Il peut être utilisé, par exemple, pour convertir des secrets partagés échangés via Diffie-Hellman en éléments clés pouvant être utilisés pour le chiffrement, le contrôle d'intégrité ou l'authentification.

Il est formellement décrit dans la RFC 5869. L'un de ses auteurs a également décrit l'algorithme dans un article complémentaire en 2010.

La norme NIST SP800-56Cr2 spécifie un schéma d'extraction puis d'extension paramétrable, notant que la RFC 5869 HKDF en est une version et citant son article pour la justification des mécanismes d'extraction et d'extension des recommandations.

Il existe des implémentations de HKDF pour C# , Go , Java , JavaScript , Perl , PHP , Python , Ruby , Rust , et d'autres langages de programmation .

Mécanisme

HKDF est la composition de deux fonctions, HKDF-Extract et HKDF-Expand : HKDF(salt, IKM, info, length) = HKDF-Expand(HKDF-Extract(salt, IKM), info, length)

Extrait de HKDF

HKDF-Extract prend un « matériel de clé d'entrée » (IKM) tel qu'un secret partagé généré à l'aide de Diffie-Hellman et un sel facultatif , et génère une clé cryptographique appelée PRK (« clé pseudo-aléatoire »). Cela agit comme un « extracteur d'aléatoire », en prenant une valeur potentiellement non uniforme d' entropie minimale élevée et en générant une valeur impossible à distinguer d'une valeur aléatoire uniforme.

HKDF-Extract est la sortie de HMAC avec le « sel » comme clé et le « IKM » comme message.

HKDF-Développer

HKDF-Expand prend le PRK, des « informations » et une longueur, et génère une sortie de la longueur souhaitée. HKDF-Expand agit comme une fonction pseudo-aléatoire basée sur le PRK. Cela signifie que plusieurs sorties peuvent être générées à partir d'une seule valeur IKM en utilisant différentes valeurs pour le champ « info ».

HKDF-Expand fonctionne en appelant HMAC de manière répétée en utilisant le PRK comme clé et le champ « info » comme message. Les entrées HMAC sont chaînées en ajoutant le bloc de hachage précédent au champ « info » et en ajoutant un compteur 8 bits incrémental.

Exemple : implémentation Python

#!/usr/bin/env python3
importer 
hashlib 
importer 
hmac
hash_function 
= 
hashlib . sha256 
# RFC5869 inclut également des vecteurs de test SHA-1
def 
hmac_digest ( clé : 
octets , 
données : 
octets ) 
-> 
octets : 
return 
hmac . new ( clé , 
données , 
fonction_hachage ) . digest ()
def 
hkdf_extract ( salt : 
octets , 
ikm : 
octets ) 
-> 
octets : 
si 
len ( salt ) 
== 
0 : 
salt 
= 
octets ( [ 0 ] 
* 
hash_function () . digest_size ) 
return 
hmac_digest ( salt , 
ikm )
def 
hkdf_expand ( prk : 
octets , 
info : 
octets , 
longueur : 
int ) 
-> 
octets : 
t 
= 
b 
okm 
= 
b 
i 
= 
0 
tandis que 
len ( okm ) 
< 
longueur : 
i 
+= 
1 
t 
= 
hmac_digest ( prk , 
t 
+ 
info 
+ 
octets ([ i ])) 
okm 
+= 
t 
return 
okm [: longueur ]
def 
hkdf ( salt : 
octets , 
ikm : 
octets , 
info : 
octets , 
longueur : 
int ) 
-> 
octets : 
prk 
= 
hkdf_extract ( salt , 
ikm ) 
return 
hkdf_expand ( prk , 
info , 
longueur )
okm 
= 
hkdf ( 
salt = octets . fromhex ( "000102030405060708090a0b0c" ), 
ikm = octets . fromhex ( "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" ), 
info = octets . fromhex ( "f0f1f2f3f4f5f6f7f8f9" ), 
longueur = 42 , 
) 
assert 
okm 
== 
octets . dehex ( 
"3cb25f25faacd57a90434f64d0362f2a" 
"2d2d0a90cf1a5a4c5db02d56ecc4c5bf" 
"34007208d5b887185865" 
)
# Assertion 
de sel de longueur nulle hkdf ( 
salt = b , 
ikm = octets . fromhex ( "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" ), 
info = b , 
length = 42 , 
) 
== 
octets . fromhex ( 
"8da4e775a563c18f715f802a063c5a31" 
"b8a11f5c5ee1879ec3454e5f3c738d2d" 
"9d201395faa4b61a96c8" 
)