Argon2

Argon2функція формування ключа, розроблена Алексом Бірюковим (англ. Alex Biryukov), Даніелем Діну (англ. Daniel Dinu) і Дмитром Ховратовичем (англ. Dmitry Khovratovich) з Університету Люксембургу в 2015 році[1].

Це сучасний простий алгоритм, спрямований на високу швидкість заповнення пам'яті та ефективне використання декількох обчислювальних блоків[2]. Алгоритм випущений під ліцензією Creative Commons.

Історія

У 2013 році був оголошений конкурс Password Hashing Competition[en] для створення нової функції хешування паролів. До нового алгоритму висувалися вимоги щодо обсягу використовуваної пам'яті, кількості проходів по блоках пам'яті і по стійкості до криптоаналізу.

У 2015 році Argon2 був оголошений переможцем конкурсу[1]. З того часу алгоритм зазнав 4 серйозні зміни. Виправлені частина описів алгоритмів генерації деяких блоків і помилки, додані рекомендовані параметри[1][2].

Вхідні дані

Argon2 використовує основні та додаткові параметри для хешування:

Основні:

  • Повідомлення (пароль) P {\displaystyle P} , довжиною від 0 {\displaystyle 0} до 2 32 1 {\displaystyle 2^{32}-1} .
  • Сіль S, довжиною від 8 {\displaystyle 8} до 2 32 1 {\displaystyle 2^{32}-1} .

Додаткові:

  • Ступінь паралелізму p {\displaystyle p} будь-яке ціле число від 1 {\displaystyle 1} до 2 24 1 {\displaystyle 2^{24}-1} — кількість потоків, на яку можна розпаралелити алгоритм.
  • Довжина тегу τ {\displaystyle \tau } , довжиною від 4 {\displaystyle 4} до 2 32 1 {\displaystyle 2^{32}-1} .
  • Об'єм пам'яті m {\displaystyle m} , ціле число кілобайтів від  8 p {\displaystyle 8p} до 2 32 1 {\displaystyle 2^{32}-1} .
  • Кількість ітерацій t {\displaystyle t} [2]

Версії алгоритму

Існують дві версії алгоритму:

Опис

Схема роботи Argon2

Argon2 працює за наступним принципом:

  1. Проводиться хешування пароля з використанням хеш-функції Blake2b.
  2. Результат хешування записується в блоки пам'яті.
  3. Блоки пам'яті перетворюються з використанням функції стиснення G {\displaystyle G} .
  4. В результаті роботи алгоритму генерується ключ (англ. Tag).

Заповнення блоків пам'яті

B [ 0 ] = H ( P , S ) {\displaystyle B[0]=H(P,S)}

B [ j ] = G ( B [ ϕ 1 ( j ) ] , B [ ϕ 2 ( j ) ] , . . . , B [ ϕ k ( j ) ] ) {\displaystyle B[j]=G(B[\phi _{1}(j)],B[\phi _{2}(j)],...,B[\phi _{k}(j)])} , j = 1... t {\displaystyle j=1...t} ,де

ϕ k ( j ) {\displaystyle \phi _{k}(j)} — функція індексування, B [ ] {\displaystyle B[]} — масив пам'яті, G {\displaystyle G} — функція стиснення, P {\displaystyle P} — повідомлення(пароль), H {\displaystyle H} — хеш-функція Blake2b.

Функції індексування залежить від версії алгоритму Argon2:

  • Argon2d — ϕ {\displaystyle \phi } залежить від попереднього блоку
  • Argon2i — ϕ {\displaystyle \phi } значення, яке визначається генератором випадкових чисел.

У разі послідовного режиму роботи функція стиснення застосовується m {\displaystyle m} раз. Для версії Argon2d на i {\displaystyle i} -му кроці на вхід функції G {\displaystyle G} подається блок з індексом ϕ ( i ) {\displaystyle \phi (i)} , обумовлений попереднім блоком м. Для версії Argon2i береться значення генератора випадкових чисел ( G {\displaystyle G} у режимі лічильника).

У разі паралельного режиму (алгоритм розпаралелюється на p {\displaystyle p} тредів) дані розподіляться по блокам матриці B [ i ] [ j ] {\displaystyle B[i][j]} , де перші блоки — результат хешування вхідних даних, а наступні задаються функцією стиснення G {\displaystyle G} за попередніми блоками і опорного блоку B 1 [ i ] [ j ] {\displaystyle B^{1}[i'][j']} :

B 1 [ i ] [ 0 ] = H (   H 0   | |   0 4 b y t e s   | |   i 4 b y t e s   ) , 0 i < p {\displaystyle B^{1}[i][0]=H'(\ H_{0}\ ||\ {\underset {4bytes}{0}}\ ||\ {\underset {4bytes}{i}}\ ),0\leq i<p}

B 1 [ i ] [ 1 ] = H (   H 0   | |   1 4 b y t e s   | |   i 4 b y t e s   ) , 0 i < p {\displaystyle B^{1}[i][1]=H'(\ H_{0}\ ||\ {\underset {4bytes}{1}}\ ||\ {\underset {4bytes}{i}}\ ),0\leq i<p}

B 1 [ i ] [ j ] = G ( B 1 [ i ] [ j 1 ] , B 1 [ i ] [ j ] ) , 0 i < p {\displaystyle B^{1}[i][j]=G(B^{1}[i][j-1],B^{1}[i'][j']),0\leq i<p}

B t [ i ] [ 0 ] = G ( B t 1 [ i ] [ q 1 ] , B 1 [ i ] [ j ] ) B t 1 [ i ] [ 0 ] {\displaystyle B^{t}[i][0]=G(B^{t-1}[i][q-1],B^{1}[i'][j'])\oplus B^{t-1}[i][0]}

B t [ i ] [ j ] = G ( B t [ i ] [ j 1 ] , B 1 [ i ] [ j ] ) B t 1 [ i ] [ j ] {\displaystyle B^{t}[i][j]=G(B^{t}[i][j-1],B^{1}[i'][j'])\oplus B^{t-1}[i][j]}

q = m p           m = m 4 p 4 p {\displaystyle q={m' \over p}\ \ \ \ \ m'=\lfloor {m \over 4p}\rfloor 4p} , де m {\displaystyle m'} — кількість блоків пам'яті розміром 1024 байта, H 0 {\displaystyle H_{0}} — хеш-функція, що приймає на вхід 32-бітове представлення вхідних параметрів на виході якої — 64-бітове значення, H {\displaystyle H'} — хеш-функція змінної довжини від H {\displaystyle H} , m {\displaystyle m} — обсяг пам'яті, t {\displaystyle t} — кількість ітерацій.

В результаті:

B f i n a l = B T [ 0 ] [ q 1 ] B T [ 1 ] [ q 1 ] . . . B T [ p 1 ] [ q 1 ] {\displaystyle B_{final}=B^{T}[0][q-1]\oplus B^{T}[1][q-1]\oplus ...\oplus B^{T}[p-1][q-1]}

T a g H ( B f i n a l ) {\displaystyle Tag\leftarrow H'(B_{final})} [3]

Знаходження опорного блоку

  • Argon2d: вибираються перші 32 біта J 1 {\displaystyle J_{1}} і наступні 32 біта J 2 {\displaystyle J_{2}} з блоків B [ i ] [ j 1 ] {\displaystyle B[i][j-1]}
  • Argon2i: ( J 1 | | J 2 ) = G 2 ( n u l l 1024 , r | | l | | s | | m | | t | | y | | i | | n u l l 968 ) {\displaystyle (J_{1}||J_{2})=G^{2}(null_{1024},{r||l||s||m'||t||y||i||null_{968}})} , где r {\displaystyle r} - номер ітерації, l {\displaystyle l}  — номер линії, y {\displaystyle y} — визначає версію (в даному випадку одиниця)

Далі визначається індекс l = J 2 m o d   p {\displaystyle l=J_{2}mod\ p} рядки, звідки береться блок. При r = 0 , s = 0 {\displaystyle r=0,s=0} за поточний номер лінії приймається значення l {\displaystyle l} . Потім визначається набір індексів R {\displaystyle R} по 2 правилами:

  1. Якщо l {\displaystyle l} збігається з номером поточного рядка, то в набір індексів додаються не всі записані раніше блоки без B [ i ] [ j 1 ] {\displaystyle B[i][j-1]}
  2. Якщо l {\displaystyle l} не збігається, то беруться блоки з усіх сегментів лінії і останніх S 1 = 3 {\displaystyle S-1=3} частин.

У підсумку, обчислюється номер блоку з r {\displaystyle r} , який приймається за опорний:

z = | R | 1 ( | R | ( ( J 1 ) 2 / 2 32 ) 2 32 ) {\displaystyle z=|R|-1-({\frac {|R|*((J_{1})^{2}/2^{32})}{2^{32}}})} [4]

Функція H'

Argon2

Blake2b — 64 бітна версія функції BLAKE, тому H {\displaystyle H'} будується наступним чином:

i f   τ     64 {\displaystyle if\ \tau \ \leq \ 64}

H ( X ) = H τ ( τ | | X ) . {\displaystyle H'(X)=H_{\tau }(\tau ||X).}

При великих τ {\displaystyle \tau } вихідне значення функції будується за першим 32 бітам блоків — A i {\displaystyle A_{i}} і останнього блоку V i {\displaystyle V_{i}}  :

r = τ / 32 2 {\displaystyle r=\lceil \tau /32\rceil -2}

V 1 H 64 ( τ | | X ) {\displaystyle V_{1}\longleftarrow H_{64}(\tau ||X)}

V r + 1 H τ 32 r ( V r ) {\displaystyle V_{r+1}\longleftarrow H_{\tau -32r}(V_{r})}

H ( X ) = A 1 | | A 2 | | . . . A r | | V r + 1 {\displaystyle H'(X)=A_{1}||A_{2}||...A_{r}||V_{r+1}}

Функція стиснення G

Заснована на функції стиснення P {\displaystyle P} Blake2b. На вхід отримує два 8192-бітних блоки і виробляє 1024-бітний блок. Спочатку два блоки складаються ( A = X Y {\displaystyle A=X\oplus Y} ), потім матриця A 8 , 8 {\displaystyle A_{8,8}} обробляється функцією P {\displaystyle P} порядково ( A Q {\displaystyle A\longrightarrow Q} ), потім отримана матриця обробляється за стовпцями ( Q Z {\displaystyle Q\longrightarrow Z} ), і на виході G видається Z A {\displaystyle Z\oplus A} [4].

Криптоаналіз

Захист від колізій: Сама функція Blake2b вважається криптографічно безпечною. Також, посилаючись на правила індексування, автори алгоритму довели відсутність колізій всередині блоків даних і низьку ймовірність їхньої появи при застосуванні функції стиснення.

Атака знаходження прообразу: нехай зловмисник підібрав m {\displaystyle m} таке, що G ( m ) = h {\displaystyle G(m)=h} , тоді для продовження даної атаки він повинен підібрати прообраз n {\displaystyle n} : H ( n ) = m {\displaystyle H(n)=m} , що неможливо. Таке ж міркування підходить для атаки знаходження другого прообразу.

Атаки по часу: якщо користувачеві необхідно адаптуватися до атаки по часу, то слід використовувати версію Argon2i, так як вона використовує незалежну пам'ять[2].

Атаки

Memory optimization attack

Ден Бонех, Генрі Корріган-Гіббс та Стюарт Шехтер у своїй роботі показали уразливість Argon2i версії 1.2. Для однопрохідної версії їх атака знижувала витрати пам'яті в 4 рази без уповільнення використання. Для багатопрохідної версії — в 2,72 рази. Пізніше, у версії 1.3 операція перезапису була замінена на XOR[5].

AB16

Джоел Елвен та Джеремая Блокі у своїх роботах довели, що їх алгоритм атаки AB16 ефективний не тільки для Argon2i-A (з першої версії специфікації), але і для Argon2i-B (з останньої версії 1.3). Вони показали, що атака на Argon2 при t = 6 {\displaystyle t=6} , використовуючи 1 гігабайт оперативної пам'яті, знижує час обчислення вдвічі.

Для ефективного захисту необхідно поставити більше 10 проходів. Але при рекомендованому підході вибору параметрів алгоритму на практиці часто може вибиратися всього лише 1 прохід. Розробники Argon2 стверджують, що, застосовуючи атаку AB16 на Argon2i-B при t 4 {\displaystyle t\geq 4} , час зменшується не більше ніж в 2 рази аж до використання 32 GB пам'яті і рекомендують використовувати число проходів, що перевищує значення двійкового логарифма від використовуваної пам'яті[6].

The ranking tradeoff attack

Ця атака є однією з найбільш ефективних для Argon2d. Вона знижує час обробки в 1,33 рази. Для Argon2i при t > 2 {\displaystyle t>2} коефіцієнт дорівнює 3 [2].

Garbage Collector Attacks

Основною умовою для представленої атаки є доступ зловмисника до внутрішньої пам'яті цільової машини або після припинення схеми хешування, або в якийсь момент, коли сам пароль ще присутній в пам'яті. Завдяки перезапису інформації з допомогою функції G {\displaystyle G} , Argon2i і Argon2d стійкі до даних атак[7].

Застосування

Argon2 оптимізований під x86-архітектуру і може бути реалізований на Linux, OS X, Windows.

Argon2d призначений для систем, де зловмисник не отримує регулярного доступу до системної пам'яті або процесора. Наприклад, для backend-серверів і криптомайнерів. При використанні одного ядра на 2-Ghz CPU і 250 Mb оперативної пам'яті з Argon2d (p=2) криптомайнінг займає 0,1 сек., а при застосуванні 4 ядер і 4 Gb пам'яті (p=8) автентифікація на backend сервері проходить за 0.5 сек.

Argon2i більше підходить для frontend-серверів і шифрування жорсткого диска. Формування ключа для шифрування на 2-Ghz CPU, використовуючи 2 ядра і 6 Гб оперативної пам'яті, з Argon2i (p=4) займає 3 сек., у той час як аутентифікація на frontend-сервері, задіявши 2 ядра і 1 Gb пам'яті з Argon2i (p=4), займає 0,5 сек.[2]

Примітки

  1. а б в г Password Hashing Competition.
  2. а б в г д е Argon, 2016.
  3. Argon, 2016, с. 294—295.
  4. а б Argon, 2016, с. 295.
  5. Henry Corrigan-Gibbs, 2016.
  6. Alwen, Blocki, 2016.
  7. Overview, 2015.

Література

  • Joel Alwen, Jeremiah Blocki. Efficiently Computing Data-Independent Memory-Hard Functions. — Advances in Cryptology – CRYPTO 2016, 2016. — С. 241—271. — ISBN 978-3-662-53008-5.
  • Dan Boneh, Henry Corrigan-Gibbs, Stuart Schechter. Balloon Hashing: A Memory-Hard Function Providing Provable Protection Against Sequential Attacks. — Advances in Cryptology – ASIACRYPT 2016, 2016. — С. 220—248. — ISBN 978-3-662-53887-6.
  • Password Hashing Competition. Архів оригіналу за 7 квітня 2019. Процитовано 16 квітня 2018.
  • Alex Biryukov, Daniel Dinu, Dmitry Khovratovich. Argon2: new generation of memory-hard functions for password hashing and other applications. — European Symposium on Security and Privacy, 2016.
  • Christian Forler, Eik List, Stefan Lucks, Jakob Wenzel. Overview of the Candidates for the Password Hashing Competition and their resistance against Garbage-Collector Attacks. — Technology and Practice of Passwords, 2015. — С. 3—18. — ISBN 978-3-319-24192-0.

Посилання

  • https://github.com/P-H-C/phc-winner-argon2 [Архівовано 2 квітня 2019 у Wayback Machine.]
  • https://www.cryptolux.org/index.php/Argon2 [Архівовано 31 березня 2019 у Wayback Machine.]
  • https://github.com/khovratovich/Argon2 [Архівовано 11 червня 2018 у Wayback Machine.] (рання версія функції)
  • п
  • о
  • р
Загальні функції
  • MD5 (скомпрометована)
  • SHA-1 (скомпрометована)
  • SHA-2
  • SHA-3
  • BLAKE2
Фіналісти SHA-3
  • BLAKE
  • Grøstl[en]
  • JH[en]
  • Skein
  • Keccak (переможець)
Інші функції
  • BLAKE3(інші мови)
  • CubeHash[en]
  • ECOH[en]
  • FSB[en]
  • Fugue[en]
  • ГОСТ 34.311-95[ru]
  • HAS-160[en]
  • HAVAL
  • Купина
  • LSH[en]
  • Lane[en]
  • MASH-1[en]
  • MASH-2[en]
  • MD2
  • MD4
  • MD6
  • MDC-2[en]
  • N-Hash
  • RIPEMD[en] (128 160 256[ru])
  • RadioGatún[en]
  • SIMD[en]
  • SM3[en]
  • SWIFFT
  • Shabal[en]
  • Snefru[en]
  • Streebog[en]
  • Tiger
  • VSH[en]
  • Whirlpool
Гешування паролів/
розтягування ключів[en]
  • Argon2
  • Balloon[en]
  • Bcrypt
  • Catena[en]
  • crypt
  • LM hash[en]
  • Lyra2[en]
  • Makwa[en]
  • PBKDF2
  • Scrypt
  • yescrypt[en]
Формування ключа
  • HKDF[en]
  • KDF1/KDF2
Коди автентифікації
повідомлення
  • CBC-MAC
  • DAA[en]
  • GMAC
  • HMAC
  • NMAC[en]
  • OMAC[en]/CMAC[en]
  • PMAC[en]
  • Poly1305[en]
  • SipHash[en]
  • UMAC[en]
  • VMAC[en]
Режими аутентифікованого
шифрування
  • CCM[en]
  • ChaCha20-Poly1305[en]
  • CWC[en]
  • EAX[en]
  • GCM
  • IAPM[en]
  • OCB[en]
Контрольні сумми та
некриптографічні[en]
функції
Атаки (огляд[en])
Конструкції
Стандартизація
  • CAESAR Competition[en]
  • CRYPTREC
  • NESSIE
  • NIST SHA-3
  • Password Hashing Competition[en]
Використання