Как мне правильно настроить параметры Argon2 в Go, чтобы потреблять меньше памяти?

Argon2 по своей природе требователен к памяти. В полуофициальной реализации Go при использовании IDKey рекомендуются следующие параметры:

key := argon2.IDKey([]byte("some password"), salt, 1, 64*1024, 4, 32)

где 1 — параметр времени, а 64*1024 — параметр памяти. Это означает, что библиотека создаст буфер размером 64 МБ при хешировании значения. В сценариях, когда одновременно может выполняться множество процедур хеширования, это создает большую нагрузку на память хоста.

В тех случаях, когда потребление памяти слишком велико, рекомендуется уменьшить параметр памяти и увеличить фактор времени:

Черновик RFC рекомендует[2] time=1, а memory=64*1024 — разумное число. Если использование такого объема памяти (64 МБ) в некоторых контекстах невозможно, для компенсации можно увеличить параметр времени.


Итак, предполагая, что я хотел бы ограничить потребление памяти до 16 МБ (1/4 рекомендуемых 64 МБ), мне все еще неясно, как мне настроить параметр time: должно ли это быть < strong>умножить на 4, чтобы произведение памяти и времени не изменилось? Или есть какая-то другая логика за корреляцией времени и памяти в игре?


person m90    schedule 10.07.2020    source источник
comment
Вы читали password-hashing.net/argon2-specs.pdf? 6.4 User-controlled parameters: NumberTof passes over the memory. The running time depends linearly on this parameter. We expectthat the user chooses this number according to the time constraints on the application. Again, there isno ”insecure value” forT. T определяет силу хеширования. Увеличение M улучшает защиту от en.wikipedia.org/wiki/Side-channel_attack.   -  person mh-cbon    schedule 13.07.2020
comment
вы можете указать любое значение. Вы будете ограничены спецификацией ваших требований и производительностью вашей системы.   -  person mh-cbon    schedule 13.07.2020
comment
Лучше не переусердствовать с этим. Параметры времени и памяти уже должны быть настроены так, чтобы отображать максимальную работу/память на пароль, которой вы можете пожертвовать. Argon2 — это смягчение неправильных паролей, а не лекарство.   -  person President James K. Polk    schedule 14.07.2020


Ответы (2)


Черновик RFC рекомендует[2] time=1, а memory=64*1024 — разумное число. Если использование такого объема памяти (64 МБ) в некоторых контекстах невозможно, для компенсации можно увеличить параметр времени.

Я думаю, что ключевым здесь является слово «компенсировать», поэтому в этом контексте оно пытается сказать: чтобы достичь такой же сложности хэширования, как IDKey([]byte("some password"), salt, 1, 64*1024, 4, 32), вы можете попробовать IDKey([]byte("some password"), salt, 4, 16*1024, 4, 32).
Но если вы хотите уменьшить сложность результата хеширования (и уменьшить накладные расходы на производительность), вы можете уменьшить размер memory uint32, игнорируя параметр time.

должно ли это быть умножено на 4, чтобы произведение памяти и времени оставалось неизменным?

Я так не думаю, я считаю, что memory здесь означает длину хэша результата, но параметр time может означать, сколько раз результат хеширования должен быть повторно хеширован, пока я не получу конечный результат.

Таким образом, эти 2 параметра не зависят друг от друга. Они просто контролируют, какую экономию затрат на перебор из-за компромиссов между временем и памятью вы хотите достичь.

person Nikko Khresna    schedule 13.07.2020

Сложность примерно равна time_cost * memory_cost (и, возможно, / parallelism). Так что если вы 0.25x стоимость памяти, вы должны 4x стоимость времени. См. также этот ответ.

// The time parameter specifies the number of passes over the memory and the
// memory parameter specifies the size of the memory in KiB.

Ознакомьтесь с самим API Argon2. Я собираюсь сделать несколько перекрестных ссылок и использовать документация по argon2-cffi. Похоже, что интерфейс go использует C-FFI (интерфейс внешних функций) под капотом, поэтому прототип должен быть таким же.

Parameters
time_cost (int) – Defines the amount of computation realized and therefore the execution time, given in number of iterations.

memory_cost (int) – Defines the memory usage, given in kibibytes.

parallelism (int) – Defines the number of parallel threads (changes the resulting hash value).

hash_len (int) – Length of the hash in bytes.

salt_len (int) – Length of random salt to be generated for each password.

encoding (str) – The Argon2 C library expects bytes. So if hash() or verify() are passed an unicode string, it will be encoded using this encoding.

type (Type) – Argon2 type to use. Only change for interoperability with legacy systems.

Действительно, если мы посмотрим на документы Go:

// The draft RFC recommends[2] time=1, and memory=64*1024 is a sensible number.
// If using that amount of memory (64 MB) is not possible in some contexts then
// the time parameter can be increased to compensate.
//
// The time parameter specifies the number of passes over the memory and the
// memory parameter specifies the size of the memory in KiB. For example
// memory=64*1024 sets the memory cost to ~64 MB. The number of threads can be
// adjusted to the numbers of available CPUs. The cost parameters should be
// increased as memory latency and CPU parallelism increases. Remember to get a
// good random salt.

Я не на 100% уверен в влиянии количества потоков, но я считаю, что это распараллеливает хэширование, и, как и в случае любой многопоточной работы, это сокращает общее время, затрачиваемое примерно на 1/N для N ядер. По-видимому, вы должны по существу установить параллелизм на количество процессоров .

person DeusXMachina    schedule 17.07.2020