HKDF: كيفية الحصول على مفاتيح جديدة وما علاقة وظائف التجزئة بها

بالنسبة لخوارزميات التشفير الحديثة ، يعد طول المفتاح أحد العوامل التي تؤثر على قوة التشفير. وفقًا لمعيار NIST ، يجب أن تكون قوة التشفير للخوارزميات 112 بت على الأقل. بالنسبة للخوارزميات المتماثلة ، يعني هذا أن الحد الأدنى لطول المفتاح يجب أن يكون 224 بت ، أما بالنسبة للخوارزميات غير المتماثلة القائمة على نظرية الأعداد (على سبيل المثال ، حل مشكلة العوامل لخوارزمية RSA ) ، فإن الحد الأدنى للطول الموثوق هو 2048 بت [1]. لا ينقذ التشفير على المنحنيات الإهليلجية من استخدام المفاتيح الكبيرة.





ولكن ماذا لو لم تكن المفاتيح الحالية طويلة بما يكفي لاستخدامها بأمان في الخوارزميات التي اخترناها؟ أم أننا بحاجة إلى مفاتيح أكثر مما لدينا؟ هذا هو المكان الذي يأتي فيه KDF (وظيفة اشتقاق المفتاح) للإنقاذ - هذه وظيفة تولد مفتاحًا سريًا قويًا أو أكثر من المفاتيح السرية بناءً على قيمة سرية معينة (يشار إليها في الأدبيات بالمفتاح الرئيسي ، وأحيانًا المفتاح الرئيسي) باستخدام وظيفة شبه عشوائية. والمهم بشكل خاص ، أنه يسمح لك بتعيين طول المفتاح الذي تم إنشاؤه كنتيجة لعملك ، وستكون قوته مماثلة لقوة مفتاح عشوائي بنفس الطول [2] ، [3].





KDF . , - HKDF, , Python'.





1. KDF

:





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





  1. "" . - "" , . ;





  2. , , "" . .





الشكل 1. خوارزمية 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) ||  ك (2) ||  ... ||  ك (ر)

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.





الشكل 2. مخطط عمل HKDF [4]
2. HKDF [4]

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





nusr_et عبر 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