Аргон2

редактировать
Функция получения ключа на основе пароля, созданная в 2015 г.

Argon2 - это функция получения ключа, которая была выбрана победителем Конкурса хеширования паролей в июле 2015. Разработан Алекс Бирюков, Даниэль Ди. nu, и Дмитрий Ховратович из Люксембургского университета. Эталонная реализация Argon2 выпущена по лицензии Creative Commons CC0 (т. Е. общественное достояние ) или Apache License 2.0 и предоставляет три связанные версии:

  • Argon2d максимизирует устойчивость к атакам взлома GPU. Он обращается к массиву памяти в порядке, зависящем от пароля, что снижает вероятность атак компромисс времени и памяти (TMTO), но вводит возможные атаки по побочным каналам..
  • Argon2i оптимизирован для сопротивляться атакам по побочным каналам. Он обращается к массиву памяти в независимом от пароля порядке.
  • Argon2id - это гибридная версия. Он следует подходу Argon2i для первого полупрохода по памяти и подходу Argon2d для последующих проходов. В интернет-проекте рекомендуется использовать Argon2id, за исключением случаев, когда есть причины предпочесть один из двух других режимов.

Все три режима допускают определение с помощью трех параметров, которые управляют:

  • время выполнения
  • требуемая память
  • степень параллелизма
Содержание
  • 1 Криптоанализ
  • 2 Алгоритм
    • 2.1 Хеш-функция переменной длины
  • 3 Ссылки
  • 4 Внешние ссылки
Криптоанализ

Хотя публичного криптоанализа, применимого к Argon2d, не существует, существует две опубликованных атаки на функцию Argon2i. Первая атака применима только к старой версии Argon2i, а вторая была расширена до последней версии (1.3)

Первая атака показывает, что возможно вычислить однопроходную функцию Argon2i, используя между четверть и пятая часть желаемого пространства без потери времени, и вычислить многопроходный Argon2i, используя только N / e < N/2.71 space with no time penalty. According to the Argon2 authors, this attack vector was fixed in version 1.3.

Вторая атака показывает, что Argon2i может быть вычислен с помощью алгоритма, который имеет сложность O (n log (n)) для всех вариантов выбора параметров σ (затраты на пространство), τ (затраты времени) и количества потоков, таких что n = σ ∗ τ. Авторы Argon2 утверждают, что эта атака неэффективна, если Argon2i используется с тремя или более проходами. Однако Джоэль Алвен и Иеремия Блоки улучшили атаку и показали, что для того, чтобы атака не удалась, Argon2i 1.3 требует более 10 проходов по памяти.

Алгоритм
Функция Argon2 Входные данные : пароль (P ): байты (0..2-1) Пароль (или сообщение) для хеширования соль (S ): байты (8..2- 1) Соль (16 байтов рекомендуется для хеширования паролей) параллелизм (p ): Число (1..2-1) Степень параллелизма (то есть количество потоков) tagLength (T ) : Число (4..2-1) Желаемое количество возвращаемых байтов memorySizeKB (m ): Number (8p..2-1) Объем памяти (в кибибайтах ) для использования итераций (t ): Число (1..2-1) Число итераций для выполнения версия (v ): Число (0x13) Текущая версия - ключ 0x13 (19 десятичных) (K ): байты (0..2-1) Необязательный ключ (ошибка: PDF говорит 0..32 байта, RFC говорит 0..2 байта) associatedData (X ) : Байт (0..2-1) Необязательные произвольные дополнительные данные hashType (y ): Number (0 = Argon2d, 1 = Argon2i, 2 = Argon2id) Вывод: tag: Bytes (tagLength) Результирующие сгенерированные байты, tagLength bytes long Создают начальный 64-байтовый блок H 0. Все входные параметры объединяются и вводятся как источник дополнительной энтропии. Исправление: RFC говорит, что H 0 является 64-битным; PDF говорит, что H 0 составляет 64 байта. Исправление: RFC говорит, что хеш - это H ^, в PDF-файле указано, что это (но не документируется, что такое). На самом деле это Blake2b. К элементам переменной длины добавляется их длина в виде 32-битных целых чисел с прямым порядком байтов. буфер ← параллелизм ∥ tagLength ∥ memorySizeKB ∥ итерации ∥ версия ∥ hashType ∥ Длина (пароль) ∥ Пароль ∥ Длина (соль) ∥ соль ∥ Длина (ключ) ∥ ключ ∥ Длина (associatedData) ∥ associatedData H 0 ← Blake2b (buffer, 64) // размер хэша Blake2b по умолчанию составляет 64 байта. Вычислите количество блоков размером 1 КБ, округлив в меньшую сторону memorySizeKB до ближайшего числа, кратного 4 * parallelism kibibytes blockCount ← Floor (memorySizeKB, 4 * parallelism) Выделить двумерный массив из блоков по 1 КиБ (строки параллелизма x столбцы columnCount) columnCount ← blockCount / parallelism; // В RFC columnCount обозначается как q Вычислить первый и второй блок (т.е. нулевой и один столбцы) каждой дорожки (т.е. строки) для i ← 0 to parallelism-1 do для каждой строки B i [0] ← Hash (H 0 ∥ 0 ∥ i, 1024) // Генерация 1024-байтовый дайджест B i [1] ← Hash (H 0 ∥ 1 ∥ i, 1024) // Создать 1024-байтовый дайджест Вычислить оставшиеся столбцы каждой дорожки для i ← от 0 до parallelism-1 do // для каждой строки для j ← 2 до columnCount-1 do // для каждого последующего столбца // индексы i 'и j' зависят от того, является ли он Argon2i, Argon2d или Argon2id (см. Раздел 3.4) i ', j' ← GetBlockIndexes (i, j) // Функция GetBlockIndexes не определена B i [j] = G (B i [j-1], B i ′ [j ′]) // G hash-функция не определена. Далее проходит, когда итераций>1 для nIteration ← 2 до итераций doдля i ← 0 до parallelism-1 do для каждой строки для j ← от до columnCount-1 do // для каждого последующего column // индексы i 'и j' зависят от того, является ли это Argon2i, Argon2d или Argon2id (см. раздел 3.4) i ′, j ′ ← GetBlockIndexes (i, j) if j == 0, то Bi[0] = B i [0] xor G (B i [columnCount-1], B i ′ [j ′]) else Bi[j] = B i [j] xor G (B i [j-1], B i ′ [j ′ ]) Вычислить последний блок C как XOR последнего столбца каждой строки C ← B 0 [columnCount-1] для i ← 1 to parallelism-1 do C ← C xor Bi[columnCount-1] Вычислить выходной тег return Hash (C, tagLength)

Хеш-функция переменной длины

Argon2 использует хеш-функцию, способную создавать дайджесты длиной до 2 байтов. Эта хеш-функция внутренне построена на Blake2.

Function Hash (message, digestSize) Входные данные: message: Bytes (0..2-1) Сообщение для хеширования digestSize: Integer (1..2) Желаемое количество возвращаемых байтов Вывод: digest: Bytes (digestSize) Полученные в результате сгенерированные байты, digestSize bytes long Hash - хеш-функция переменной длины, построенная с использованием Blake2b, способная создание дайджестов до 2 байтов. Если запрошенный размер дайджеста составляет 64 байта или меньше, тогда мы используем Blake2b напрямую, если (digestSize <= 64), затемreturn Blake2b (digestSize ∥ message, digestSize) // объединяем 32-битный little endian digestSize с байтами сообщения. Для желаемых хэшей размером более 64 байтов (например, 1024 байта для блоков Argon2) мы используем Blake2b для генерации вдвое большего количества необходимых 64-байтовых блоков, а затем используем только 32 -байты из каждого блока Вычислить количество целых блоков (зная, что мы будем использовать только 32 байта из каждого блока) r ← Ceil (digestSize / 32) -1; Сгенерируйте r целых блоков. Начальный блок генерируется из сообщения V 1 ← Blake2b (digestSize ∥ message, 64); Последующие блоки генерируются из предыдущих блоков для i ← 2 tor doVi← Blake2b (V i-1, 64) Генерируют последний (возможно частичный) блок partialBytesNeeded ← digestSize - 32 * р; V r + 1 ← Blake2b (V r, partialBytesNeeded) Объедините первые 32 байта каждого блока V i (кроме, возможно, частичного последнего блока, который мы берем все это) Пусть A i представляет младшие 32 байта блока V ireturn A1∥ A 2 ∥... ∥ A r ∥ V r + 1
Ссылки
Внешние ссылки
Последняя правка сделана 2021-06-12 02:33:39
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте