Argon2

Argon2

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

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

История

В 2013 году был объявлен конкурс Password Hashing Competition[англ.] о создании новой функции хеширования паролей. К новому алгоритму предъявлялись требования по объёму используемой памяти, количеству проходов по блокам памяти и по устойчивости к криптоанализу.

В 2015 году Argon2 был объявлен победителем конкурса[1]. С того времени алгоритм претерпел 4 серьёзных изменения. Исправлены часть описаний алгоритмов генерации некоторых блоков и опечатки, добавлены рекомендуемые параметры[1][3].

Входные данные

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} [4]

Версии алгоритма

Существуют две версии алгоритма:

Описание

Схема работы 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)} , определяемый предыдущим блоком ϕ ( i ) = g ( B [ i ] ) {\displaystyle \phi (i)=g(B[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})} [5]

Нахождение опорного блока

  • 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}}})} [6]

Функция 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 {\displaystyle G} выдаётся Z A {\displaystyle Z\oplus A} [6].

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

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

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

Атаки по времени: если пользователю необходимо адаптироваться к атаке по времени, то следует использовать версию Argon2i, так как она использует независимую память[7].

Атаки

Memory optimization attack

Дэн Боне, Henry Corrigan-Gibbs и Stuart Schechter в своей работе показали уязвимость Argon2i версии 1.2. Для однопроходной версии их атака снижала расход памяти в 4 раза без замедления выполнения. Для многопроходной версии — в 2,72 раза. Позднее, в версии 1.3 операция перезаписи была заменена на XOR[8].

AB16

Joel Alwen и Jeremiah Blocki в своих работах доказали, что их алгоритм атаки AB16 эффективен не только для Argon2i-A (из первой версии спецификации), но и для Argon2i-B (из последней версии 1.3). Они показали, что атака на Argon2 при t = 6 {\displaystyle t=6} , используя 1 GB ОЗУ, снижает время вычисления в два раза. Для эффективной защиты необходимо задать больше 10 проходов. Но при рекомендуемом подходе выбора параметров алгоритма на практике часто может выбираться всего лишь 1 проход. Разработчики Argon2 утверждают, что, применяя атаку AB16 на Argon2i-B при t 4 {\displaystyle t\geq 4} , время уменьшается не более чем в 2 раза вплоть до использования 32 GB памяти и рекомендуют использовать число проходов, превышающее значение двоичного логарифма от размера[уточнить] используемой памяти[9].

The ranking tradeoff attack

Данная атака является одной из самых эффективных для Argon2d. Она снижает время обработки в 1,33 раза. Для Argon2i при t > 2 {\displaystyle t>2} коэффициент равен 3[10].

Garbage collector attacks

Основным условием для представленной атаки является доступ злоумышленника к внутренней памяти целевой машины либо после прекращения схемы хеширования, либо в какой-то момент, когда сам пароль ещё присутствует в памяти. Благодаря перезаписи информации с помощью функции G {\displaystyle G} , Argon2i и Argon2d устойчивы к данным атакам[11].

Применение

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

Argon2d предназначен для систем, где злоумышленник не получает регулярного доступа к системной памяти или процессору. Например, для backend-серверов и криптомайнеров[источник не указан 754 дня]. При использовании одного ядра на 2-GHz CPU и 250 MB оперативной памяти с Argon2d (p=2) криптомайнинг занимает 0,1 с, а при применении 4 ядер и 4 GB памяти (p=8) аутентификация на backend сервере проходит за 0,5 с[источник не указан 754 дня].

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

Примечания

  1. 1 2 3 4 Password Hashing Competition.
  2. Argon, 2016, с. 293.
  3. Argon, 2016, с. 292.
  4. Argon, 2016, с. 294.
  5. Argon, 2016, с. 294—295.
  6. 1 2 Argon, 2016, с. 295.
  7. Argon, 2016, с. 296—297.
  8. Henry Corrigan-Gibbs, 2016.
  9. Alwen, Blocki, 2016.
  10. Argon, 2016, с. 297.
  11. Overview, 2015.
  12. Argon, 2016, с. 300.

Литература

  • Joel Alwen, Jeremiah Blocki. Efficiently Computing Data-Independent Memory-Hard Functions. — Advances in Cryptology – CRYPTO 2016, 2016. — P. 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. — P. 220—248. — ISBN 978-3-662-53887-6.
  • Password Hashing Competition  (неопр.).
  • 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. — P. 3—18. — ISBN 978-3-319-24192-0.

Ссылки

  • https://github.com/P-H-C/phc-winner-argon2
  • https://www.cryptolux.org/index.php/Argon2
  • https://github.com/khovratovich/Argon2 (ранняя версия функции)
Перейти к шаблону «Хеш-алгоритмы»
Общего назначения
Криптографические
Функции формирования ключа
Контрольное число (сравнение)
Применение хешей