
Para algoritmos de criptografia modernos, um dos fatores que afetam a força criptográfica é o comprimento da chave. De acordo com o padrão NIST , a força criptográfica dos algoritmos deve ser de pelo menos 112 bits. Para algoritmos simétricos, isso significa que o comprimento mínimo da chave deve ser de 224 bits, para os assimétricos baseados na teoria dos números (por exemplo, resolvendo o problema de fatoração para o algoritmo RSA ), o comprimento mínimo confiável é de 2.048 bits [1]. A criptografia em curvas elípticas não evita o uso de chaves grandes.
Mas e se as chaves existentes não forem longas o suficiente para serem usadas com segurança em nossos algoritmos escolhidos? Ou precisamos de mais chaves do que temos? É aqui que a KDF (função de derivação de chave) vem para o resgate - esta é uma função que gera uma ou mais chaves secretas criptograficamente fortes com base em um determinado valor secreto (na literatura referido como a chave mestra, e às vezes a chave mestra) usando uma função pseudo-aleatória. E o que é especialmente importante, ele permite que você defina o comprimento da chave gerada como resultado do seu trabalho, e sua força será a mesma de uma chave aleatória do mesmo comprimento [2], [3].
KDF . , - HKDF, , Python'.
1. KDF
, KDF , "--" (- - extract-and-expand):
"" . - "" , . ;
, , "" . .
![Fig 1. Algoritmo de KDF [4] Fig 1. Algoritmo de KDF [4]](https://habrastorage.org/getpro/habr/upload_files/1c8/bcc/d4e/1c8bccd4ef00c38fffa625fe7c0734a2.png)
.
Randomness Extraction:
- - :
:
SKM (Source Keying Material) - ( ) , PRK, - . , "" KDF;
XTR (randomness eXTRactor) - . , SKM PRK. , ( );
PRK (PseudoRandom Key) - . ;
XTSalt (eXTractor Salt) - , .. ( ) , , . .
, . - KDF . , HKDF, , -.
Key Expansion:
(PRK) L, . :
:
PRF* (PseudoRandom Function with variable length) - , . , counter feedback mode;
CTXInfo (context information) - ( , , , ). , , , ;
PRK - ;
DKM (Derived Keying Material) - L.
, . ? ?
, . , KDF "" , . , "" , .
, - (-) , , . , premaster secret TLS , (IETF). , , , , PRF* ( PRF* ).
2. HKDF
HKDF (HMAC Key Derivation Function) KDF. KDF ( PRF*), , HMAC.
HKDF
HMAC , - , - , . HashLen ( ), . || ("") . HMAC(key, a || b) , - key a b.
, HKDF :
XTS, SKM CTXInfo , KDF, K(i), i = 1,...,t :
PRK = HMAC-Hash(XTS, SKM) - , (SKM) (PRK). PRK , HMAC (HMAC-Hash) HashLen . , - , "" - . , SKM , PRK .
K(1) = HMAC-Hash(PRK, CTXinfo || 0),
K(i+1) = HMAC-Hash(PRK, K(i) || CTXinfo || i), 1 ≤ i < t,
t = L/HashLen - "", L. i . , HashLen, L K. L: L ≤ 255 * HashLen.
![Fig 2. Esquema de trabalho de HKDF [4] Fig 2. Esquema de trabalho de HKDF [4]](https://habrastorage.org/getpro/habr/upload_files/205/a2a/ff1/205a2aff1c895a67d1937409307ad397.png)
KDF, - ; , HashLen. , , -, XTSalt PRK.

. . , "" , . , , , .. , HKDF , . SKM.
3. HKDF
HKDF : Java, JavaScript, PHP, Python. , , , , :
import hashlib
import hmac
from math import ceil
hash_len = 32
def hmac_sha256(key, data):
return hmac.new(key, data, hashlib.sha256).digest()
def hkdf(length: int, ikm, salt: bytes = b"", CTXinfo: bytes = b"") -> bytes:
# - , , ,
# hash_len:
if len(salt) == 0:
salt = bytes([0] * hash_len)
# :
# -:
prk = hmac_sha256(salt, ikm)
k_i = b"0" # - 0
dkm = b"" # Derived Keying Material
t = ceil(length / hash_len)
# : - K(i),
# . ,
# K(i) K(i-1):
for i in range(t):
k_i = hmac_sha256(prk, k_i + CTXinfo + bytes([1 + i]))
dkm += k_i
# hash_len, length :
return dkm[:length]
:
>>> output = hkdf(100, b"input_key", b"add_some_salt")
>>>
>>> print(''.join('{:02x}'.format(byte) for byte in output))
2bcd8350cc31b6945b23b2a47add4d5ec4b1bd9fad0387590bf4e9f4d34ea456e63267c765e7cd5451df1f6f18f41eaba20de594fd8c6a008120276438d18fc4122ec152fff03204c966261b60408a569b6b0e3527ae4a34570c62b2d060fd15f3176a36
>>>
>>> print(len(out))
100
, hkdf
output "input_key" "add_some_salt". , , , . . 100 , , !
:
IETF: https://tools.ietf.org/html/rfc5869
: https://eprint.iacr.org/2010/264
- KDF: https://www.coursera.org/lecture/crypto/key-derivation-A1ETP
[1] https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf, 9.
[2] https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-108.pdf, 16-19;
[3] https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r5.pdf, 108-109;
[4] Diretrizes gerais para o uso de KDF: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Cr2.pdf , pp. 17, 22