HKDF: cómo obtener nuevas claves y qué funciones hash tienen que ver con eso

Para los algoritmos de cifrado modernos, uno de los factores que afectan la fuerza criptográfica es la longitud de la clave. Según el estándar NIST , la fuerza criptográfica de los algoritmos debe ser de al menos 112 bits. Para los algoritmos simétricos esto significa que la longitud mínima de la clave debe ser de 224 bits, para las asimétricas basadas en la teoría de números (por ejemplo, resolviendo el problema de factorización para el algoritmo RSA ), la longitud mínima confiable es de 2048 bits [1]. La criptografía de curva elíptica no impide el uso de claves grandes.





Pero, ¿qué pasa si las claves existentes no son lo suficientemente largas para ser utilizadas de forma segura en nuestros algoritmos elegidos? ¿O necesitamos más llaves de las que tenemos? Aquí es donde KDF (función de derivación de claves) viene al rescate : esta es una función que genera una o más claves secretas criptográficamente seguras basadas en un valor secreto dado (en la literatura se conoce como la clave maestra y, a veces, la clave maestra) utilizando una función pseudoaleatoria. Y lo que es especialmente importante, le permite establecer la longitud de la clave generada como resultado de su trabajo, y su fuerza será la misma que la de una clave aleatoria de la misma longitud [2], [3].





KDF . , - HKDF, , Python'.





1. KDF

:





, KDF , "--" (- - extract-and-expand):





  1. "" . - "" , . ;





  2. , , "" . .





Fig 1. Algoritmo de KDF [4]
1. KDF [4]

.





Randomness Extraction:

- - :





PRK = XTR (XTSalt, SKM)

:





  • SKM (Source Keying Material) - ( ) , PRK, - . , "" KDF;





  • XTR (randomness eXTRactor) - . , SKM PRK. , ( );





  • PRK (PseudoRandom Key) - . ;





  • XTSalt (eXTractor Salt) - , .. ( ) , , . .





, . - KDF . , HKDF, , -.





Key Expansion:

(PRK) L, . :





DKM = PRF ^ {*} (PRK, CTXinfo, 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 :





HKDF (XTS, SKM, CTXinfo, L) = K = K (1) ||  K (2) ||  ... ||  K (t)

XTS, SKM CTXInfo , KDF, K(i), i = 1,...,t :





  1. PRK = HMAC-Hash(XTS, SKM) - , (SKM) (PRK). PRK , HMAC (HMAC-Hash) HashLen . , - , "" - . , SKM , PRK .





  2. 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 trabajo de HKDF [4]
2. HKDF [4]

KDF, - ; , HashLen. , , -, XTSalt PRK.





@nusr_et a través de Instagram
@nusr_et via Instagram

. . , "" , . , , , .. , 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 , , !





:












All Articles