Аргон2
Argon2 — это функция получения ключей , которая была выбрана победителем конкурса хеширования паролей 2015 года . [1] [2] Его разработали Алексей Бирюков , Даниэль Дину и Дмитрий Ховратович из Университета Люксембурга . [3] Эталонная реализация Argon2 выпущена под лицензией Creative Commons CC0 (т. е. общедоступной ) или лицензией Apache 2.0 и предоставляет три связанные версии:
- Argon2d максимизирует устойчивость к взломам графического процессора . Он обращается к массиву памяти в порядке, зависящем от пароля, что снижает вероятность атак с использованием компромисса между временем и памятью (TMTO), но приводит к возможным атакам по побочным каналам .
- Argon2i оптимизирован для защиты от атак по побочным каналам. Он обращается к массиву памяти в порядке, независимом от пароля.
- Argon2id — гибридная версия. Он соответствует подходу Argon2i для первого полупрохода по памяти и подходу Argon2d для последующих проходов. RFC 9106 рекомендует использовать Argon2id, если вы не знаете разницы между типами или считаете атаки по побочным каналам реальной угрозой. [4]
Все три режима позволяют указать три параметра, которые контролируют:
- время выполнения
- требуется память
- степень параллелизма
Криптоанализ [ править ]
применимого к Argon2d, не существует Хотя общедоступного криптоанализа, , существуют две опубликованные атаки на функцию Argon2i. Первая атака применима только к старой версии Argon2i, а вторая расширена до последней версии (1.3). [5]
Первая атака показывает, что можно вычислить однопроходную функцию Argon2i, используя от четверти до пятой желаемого пространства без потери времени, и вычислить многопроходную функцию Argon2i, используя только N / e (≈ N /2,72). пространство без штрафа по времени. [6] По словам авторов Argon2, этот вектор атаки был исправлен в версии 1.3. [7]
Вторая атака показывает, что Argon2i можно вычислить с помощью алгоритма сложности O( n 7/4 log( n )) для всех вариантов выбора параметров σ (стоимость пространства), τ (затраты времени) и количества потоков таких, что n = σ ∗ τ . [8] Авторы Argon2 утверждают, что эта атака неэффективна, если Argon2i используется с тремя и более проходами. [7] Однако Жоэль Алвен и Джеремайя Блоки улучшили атаку и показали, что для того, чтобы атака не удалась, Argon2i v1.3 необходимо более 10 проходов по памяти. [5]
Чтобы решить эти проблемы, RFC9106 рекомендует использовать Argon2id для значительного смягчения таких атак. [9]
Алгоритм [ править ]
Источник: [4]
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 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 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] = Bi[0] xor G(Bi[columnCount-1], Bi′[j′]) else Bi[j] = Bi[j] xor 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)
Хэш-функция переменной длины [ править ]
Argon2 использует хеш-функцию, способную создавать дайджесты до 2 32 длиной в байтах. Эта хеш-функция встроена в Blake2 .
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)-2; 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
Рекомендуемые минимальные параметры [ править ]
По состоянию на май 2023 года OWASP в шпаргалке по хранению паролей людям рекомендуется «использовать Argon2id с минимальной конфигурацией 19 МБ памяти, количеством итераций 2 и 1 степенью параллелизма». [10]
OWASP рекомендует отдавать предпочтение Argon2id перед Argon2d и Argon2i, поскольку он обеспечивает сбалансированную устойчивость как к атакам на основе графического процессора, так и к атакам по побочным каналам. [10]
OWASP далее отмечает, что следующие параметры Argon2id обеспечивают эквивалентную криптографическую стойкость и просто компенсируют использование памяти для вычислительной рабочей нагрузки: [10]
- Память: 46 МБ, Итерации: 1, Параллелизм: 1
- Память: 19 МБ, Итерации: 2, Параллелизм: 1
- Память: 12 МБ, Итерации: 3, Параллелизм: 1
- Память: 9 МБ, Итерации: 4, Параллелизм: 1
- Память: 7 МБ, Итерации: 5, Параллелизм: 1
Ссылки [ править ]
- ^ "Соревнование по хешированию паролей"
- ^ Йос Ветцелс (08 февраля 2016 г.). «Открытый Сезам: соревнование по хешированию паролей и Argon2». arXiv : 1602.03097 [ cs.CR ].
- ^ Argon2: функция жесткой памяти для хеширования паролей и других приложений , Алекс Бирюков и др., 1 октября 2015 г.
- ^ Jump up to: Перейти обратно: а б Бирюков, Алекс; Дину, Дэниел; Ховратович Дмитрий; Йозефссон, Саймон (сентябрь 2021 г.). «Функция Argon2 с жесткой памятью для приложений хеширования паролей и доказательства работы» . Проверено 9 сентября 2021 г.
- ^ Jump up to: Перейти обратно: а б Джоэл Алвен; Иеремия Блоки (5 августа 2016 г.). К практическим атакам на Argon2i и хэширование воздушных шаров (PDF) (Отчет).
- ^ Генри; Корриган-Гиббс; Дэн Бонех; Стюарт Шехтер (14 января 2016 г.). Хеширование номеров: доказуемо жесткие хеш-функции с независимыми от данных шаблонами доступа (PDF) (отчет).
- ^ Jump up to: Перейти обратно: а б "[Cfrg] Argon2 v.1.3" . www.ietf.org . Проверено 30 октября 2016 г.
- ^ Джоэл Алвен; Иеремия Блоки (19 февраля 2016 г.). Эффективное вычисление независимых от данных функций памяти (PDF) (отчет).
- ^ «Рекомендации» . Функция Argon2 с жесткой памятью для приложений хеширования паролей и доказательства работы . IETF . Сентябрь 2021. сек. 7.4. дои : 10.17487/RFC9106 . РФК 9106 . Проверено 12 июля 2023 г.
- ^ Jump up to: Перейти обратно: а б с «Шпаргалка по хранению паролей» . Серия шпаргалок OWASP . ОВАСП . Проверено 17 мая 2023 г.
Внешние ссылки [ править ]
- Репозиторий исходного кода Argon2 на Github
- Спецификация аргона2
- Соревнования по хешированию паролей
- Страница Uni.Lu Argon2
- Хеширование воздушных шаров: функция с жесткими требованиями к памяти, обеспечивающая доказуемую защиту от последовательных атак
- RFC 9106 Argon2 — функция жесткой памяти для приложений хеширования паролей и доказательства работы