HKDF: como obter novas chaves e o que funções hash têm a ver com isso

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):





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

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





@nusr_et via 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