Argon2

Vikipedi, özgür ansiklopedi

Argon2, Temmuz 2015'te Parola Özetleme Yarışmasının galibi olarak seçilen anahtar türetme fonksiyonudur.[1][2] Lüksemburg Üniversitesi'nden Alex Biryukov, Daniel Dinu ve Dmitry Khovratovich tarafından tasarlanmıştır.[3] Argon2'nin referans uygulaması, CC0 lisansı (yani kamu malı) veya Apache License 2.0 altında yayınlanmış ve üç ilgili sürüm sağlamıştır:

  • Argon2d, GPU kırılma saldırılarına karşı direnci en üst düzeye çıkarır. Argon2d, bellek dizisine, parola bağımlı bir sırayla erişir; bu da zaman-bellek takası (TMTO) saldırılarının olasılığını azaltır, ancak olası yan kanal saldırıları sunar.
  • Argon2i, yan kanal saldırılarına dayanacak şekilde optimize edilmiştir. Bellek dizisine parola bağımsız bir sırada erişir.
  • Argon2id hibrit bir versiyondur. İlk bellek geçişi için Argon2i yaklaşımını ve sonraki geçişler için Argon2d yaklaşımını izler. İnternet taslağı,[4] diğer iki moddan birinin tercih edilmesini gerektiren durumlar olması haricinde Argon2id kullanılmasını önerir.

Üç modun her biri, aşağıda verilen üç parametre ile tanımlama yapmaya izin verir.

  • çalışma süresi
  • hafıza gerekliliği
  • paralellik derecesi

Kriptanaliz[değiştir | kaynağı değiştir]

Argon2d'ye uygulanabilecek genel bir kripto analizi olmamasına rağmen, Argon2i fonksiyonuna karşı yayınlanan iki saldırı vardır. İlk saldırı sadece Argon2i'nin eski sürümüne uygulanabilirken, ikincisi en son sürüme kadar uzatılmıştır (1.3)[5]

İlk saldırı, zaman cezası[6] olmadan, istenen alanın çeyreği ile beşte biri arasında kullanılması ile, tek geçişli Argon2i fonksiyonunu hesaplamanın ve yine zaman cezası olmadan, sadece N/e < N/2.71 alanı kullanarak birçok geçişli Argon2i hesaplamanın mümkün olduğunu göstermektedir. Argon2 yazarlarına göre, bu saldırı vektörü 1.3 sürümünde düzeltilmiştir.[7]

İkinci saldırı, Argon2i'nin, seçilen tüm parametreler için, örneğin; σ(alan maliyeti), τ(zaman maliyeti) ve n=στ[8] olan izlek sayısı, karmaşıklığı O(n7/4 log(n)) olan bir algoritma ile hesaplanabildiğini göstermektedir.

Argon2 yazarları, Argon2i üç veya daha fazla geçişle kullanılırsa bu saldırının etkili olmadığını iddia eder.[7] Bununla birlikte, Joël Alwen ve Jeremiah Blocki saldırıyı iyileştirmiş ve saldırının başarısız olması için Argon2i 1.3'ün bellek üzerinde 10'dan fazla geçişe ihtiyaç duyduğunu göstermiştir.[5]

Algoritma[değiştir | kaynağı değiştir]

Function Argon2
   Inputs:
      password (P):      Bytes (0..232-1)    Password (or message) to be hashed
      salt (S):          Bytes (8..232-1)    Salt (16 bytes recommended for password hashing)
      parallelism (p):   Number (1..224-1)   Degree of parallelism (i.e. number of threads)
      tagLength (T):     Number (4..232-1)   Desired number of returned bytes
      memorySizeKB (m):  Number (8p..232-1)  Amount of memory (in [./https://en.wikipedia.org/wiki/Kibibyte 30 Mart 2019 tarihinde Wayback Machine sitesinde arşivlendi. kibibytes]) to use
      iterations (t):    Number (1..232-1)   Number of iterations to perform
      version (v):       Number (0x13)      The current version is 0x13 (19 decimal)
      key (K):           Bytes (0..232-1)    Optional key (Errata: PDF says 0..32 bytes, RFC says 0..232 bytes)
      associatedData (X): Bytes (0..232-1)    Optional arbitrary extra data
      hashType (y):      Number (0=Argon2d, 1=Argon2i, 2=Argon2id)
   Output:
      tag:               Bytes (tagLength)   The resulting generated bytes, tagLength bytes long

   Generate initial 64-byte block H0.
   All the input parameters are concatenated and input as a source of additional entropy.
   Errata: RFC says H0 is 64-bits; PDF says H0 is 64-bytes.
   Errata: RFC says the Hash is H^, the PDF says it's ℋ (but doesn't document what ℋ is). It's actually Blake2b.
   Variable length items are prepended with their length as 32-bit little-endian integers.
   buffer ← parallelism ∥ tagLength ∥ memorySizeKB ∥ iterations ∥ version ∥ hashType
         ∥ Length(password)       ∥ Password
         ∥ Length(salt)           ∥ salt
         ∥ Length(key)            ∥ key
         ∥ Length(associatedData) ∥ associatedData
   H0 ← Blake2b(buffer, 64) //default hash size of Blake2b is 64-bytes

   Calculate number of 1 KB blocks by rounding down memorySizeKB to the nearest multiple of 4*parallelism [./https://en.wikipedia.org/wiki/Kibibyte 30 Mart 2019 tarihinde Wayback Machine sitesinde arşivlendi. kibibytes]
   blockCount ← Floor(memorySizeKB, 4*parallelism)

   Allocate two-dimensional array of 1 KiB blocks (parallelism rows x columnCount columns)
   columnCount ← blockCount / parallelism;  //In the RFC, columnCount is referred to as q

   Compute the first and second block (i.e. column zero and one) of each lane (i.e. row)
   for i ← 0 to parallelism-1 do for each row
      Bi[0] ← Hash(H0 ∥ 0 ∥ i, 1024) //Generate a 1024-byte digest
      Bi[1] ← Hash(H0 ∥ 1 ∥ i, 1024) //Generate a 1024-byte digest

   Compute remaining columns of each lane
   for i ← 0 to parallelism-1 do //for each row
      for j ← 2 to columnCount-1 do //for each subsequent column
         //i' and j' indexes depend if it's Argon2i, Argon2d, or Argon2id (See section 3.4)
         i′, j′ ← GetBlockIndexes(i, j)  //the GetBlockIndexes function is not defined
         Bi[j] = G(Bi[j-1], Bi′[j′]) //the G hash function is not defined

   Further passes when iterations > 1
   for nIteration ← 2 to iterations do
      for i ← 0 to parallelism-1 do for each row
        for j ← 0 to columnCount-1 do //for each subsequent column
           //i' and j' indexes depend if it's Argon2i, Argon2d, or Argon2id (See section 3.4)
           i′, j′ ← GetBlockIndexes(i, j)
           if j == 0 then 
             Bi[0] = G(Bi[columnCount-1], Bi′[j′])
           else
             Bi[j] = G(Bi[j-1], Bi′[j′])

   Compute final block C as the XOR of the last column of each row
   C ← B0[columnCount-1]
   for i ← 1 to parallelism-1 do
      C ← C xor Bi[columnCount-1]

   Compute output tag
   return Hash(C, tagLength)

Değişken uzunluklu özet fonksiyonu[değiştir | kaynağı değiştir]

Argon2, 232 byte uzunluğuna kadar özet üretebilen özet fonksiyonunu kullanır. Bu özet fonksiyonu dahili olarak Blake2 üzerine kuruludur.

Function Hash(message, digestSize)
   Inputs:
      message:        Bytes (0..232-1)     Message to be hashed
      digestSize:     Integer (1..232)     Desired number of bytes to be returned
   Output:
      digest:         Bytes (digestSize)   The resulting generated bytes, digestSize bytes long

   Hash is a variable-length hash function, built using Blake2b, capable of generating
   digests up to 232 bytes.

   If the requested digestSize is 64-bytes or lower, then we use Blake2b directly
   if (digestSize <= 64) then
      return Blake2b(digestSize ∥ message, digestSize) //concatenate 32-bit little endian digestSize with the message bytes

   For desired hashes over 64-bytes (e.g. 1024 bytes for Argon2 blocks),
   we use Blake2b to generate twice the number of needed 64-byte blocks,
   and then only use 32-bytes from each block

   Calculate the number of whole blocks (knowing we're only going to use 32-bytes from each)
   r ← Ceil(digestSize/32)-1;

   Generate r whole blocks.
   Initial block is generated from message
   V1 ← Blake2b(digestSize ∥ message, 64);
   Subsequent blocks are generated from previous blocks
   for i ← 2 to r do
      Vi ← Blake2b(Vi-1, 64)
   Generate the final (possibly partial) block
   partialBytesNeeded ← digestSize – 32*r;
   Vr+1 ← Blake2b(Vr, partialBytesNeeded)

   Concatenate the first 32-bytes of each block Vi
   (except the possibly partial last block, which we take the whole thing)
   Let Ai represent the lower 32-bytes of block Vi
   return A1 ∥ A2 ∥ ... ∥ Ar ∥ Vr+1

Kaynakça[değiştir | kaynağı değiştir]

  1. ^ ""Şifre Karma Yarışması"". 7 Nisan 2019 tarihinde kaynağından arşivlendi. Erişim tarihi: 31 Mart 2019. 
  2. ^ Jos Wetzels (8 Şubat 2016). "Open Sesame: The Password Hashing Competition and Argon2" (PDF). 21 Eylül 2020 tarihinde kaynağından arşivlendi (PDF). Erişim tarihi: 7 Nisan 2019. 
  3. ^ Argon2: şifre karma ve diğer uygulamalar için hafızası zorlama fonksiyonu 5 Haziran 2019 tarihinde Wayback Machine sitesinde arşivlendi., Alex Biryukov, et al, 1 Ekim 2015
  4. ^ "Hafızaya dayanıklı Argon2 şifre hash ve çalışma kanıtı işlevi". draft-irtf-cfrg-argon2-03. 31 Mart 2019 tarihinde kaynağından arşivlendi. Erişim tarihi: 16 Ağustos 2017. 
  5. ^ a b Joël Alwen, Jeremiah Blocki (5 Ağustos 2016). "Towards Practical Attacks on Argon2i and Balloon Hashing" (PDF). 11 Haziran 2020 tarihinde kaynağından arşivlendi (PDF). Erişim tarihi: 7 Nisan 2019. 
  6. ^ Henry Corrigan-Gibbs, Dan Boneh, Stuart Schechter (14 Ocak 2016). "Balloon Hashing: Provably Space-Hard Hash Functions with Data-Independent Access Patterns" (PDF). 12 Aralık 2018 tarihinde kaynağından arşivlendi (PDF). Erişim tarihi: 31 Mart 2019. 
  7. ^ a b "[Cfrg] Argon2 v.1.3". www.ietf.org. 30 Nisan 2016 tarihinde kaynağından arşivlendi. Erişim tarihi: 30 Ekim 2016. 
  8. ^ Joel Alwen, Jeremiah Blocki (19 Şubat 2016). "Efficiently Computing Data-Independent Memory-Hard Functions" (PDF). 12 Aralık 2018 tarihinde kaynağından arşivlendi (PDF). Erişim tarihi: 7 Nisan 2019. 

Dış bağlantılar[değiştir | kaynağı değiştir]