Алгоритм Argon2 в PHP7: понимание параметра time_cost

Я пытаюсь реализовать алгоритм Argon2 в библиотеке аутентификации. Я хочу дать пользователям несколько полезных советов по настройке параметров.

Хотя я понимаю, как параметры memory_cost и threads влияют на алгоритм, я не могу понять параметр time_cost.

Что говорится в документе по PHP:

time_cost (integer) — максимальное количество времени, которое может потребоваться для вычисления хэша Argon2. По умолчанию PASSWORD_ARGON2_DEFAULT_TIME_COST.

Опрос 1 – значение по умолчанию – 2. Кажется, оно представляет собой время, но, к сожалению, единица измерения отсутствует. Это в секундах? Миллисекунды?

Этот SO answer говорит по умолчанию 2 секунды.

Что говорится в спецификациях Argon2:

В главе 3.1 Входные данные здесь нет упоминания о времени, только о количестве итераций.

Количество итераций t (используется для настройки времени работы независимо от объема памяти) может быть любым целым числом от 1 до 2^32−1;

Значение, связанное со временем, определено в Главе 9 Рекомендуемые параметры, в нем говорится:

Вычислите максимальное количество x времени (в секундах), которое может позволить себе каждый вызов

[...]

Запустите схему типа y, памяти m и h дорожек и потоков, используя разное количество проходов t. Вычислите максимальное t, чтобы время работы не превышало x. Если оно превышает x даже для t = 1, уменьшите m соответственно.

Хэшируйте все пароли с только что определенными значениями m, h и t.

Вопрос 2. Значит ли это, что PHP предоставляет количество времени x и определяет правильное количество итераций t?

Что говорится в PHP RFC:

Стоимость времени, определяющая время выполнения алгоритма и количество итераций.

[...]

Стоимость времени представляет собой количество запусков алгоритма хеширования.

Опрос 3. Они говорят как о времени, так и о количестве итераций. Теперь я еще больше запутался. Это время или количество итераций? Если я запускаю хэш с time_cost = 2, значит ли это, что это займет 2 секунды?


Эталон

Чтобы помочь мне немного понять, я сделал этот небольшой тестовый скрипт. Я получил следующий результат (1 поток):

m_cost (MB) |  1  |  2  |  4  |  8  | 16  | 32  | 64  | 128 | 256
            =====================================================
t_cost=1    |  1  |  2  |  5  | 10  | 24  | 46  | 90  | 188 | 348
t_cost=2    |  2  |  4  |  8  | 18  | 39  | 75  | 145 | 295 | 636
t_cost=3    |  3  |  6  | 12  | 26  | 53  | 102 | 209 | 473 | 926
t_cost=4    |  5  |  9  | 30  | 56  | 78  | 147 | 309 | 567 |1233
t_cost=5    |  4  |  9  | 19  | 40  | 79  | 165 | 359 | 690 |1372
t_cost=6    |  5  | 12  | 23  | 49  | 93  | 198 | 399 | 781 |1777
t_cost=7    |  6  | 14  | 29  | 53  | 118 | 259 | 508 |1036 |2206
t_cost=8    |  8  | 16  | 33  | 82  | 179 | 294 | 528 |1185 |2344

Я до сих пор не понимаю, как time_cost может быть временем в секундах.

Если это верхняя граница (имеется в виду максимальное время, в течение которого он может работать), то это даже не полезно. Например, t_cost=8 и m_cost=16MB могут показаться разумными, так как их выполнение занимает около 200 мс. Но это означает, что однажды алгоритм может выполняться до 8 секунд? Юзабилити будет катастрофическим!


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

Но это действительно сбивает с толку. Поскольку это связано с безопасностью, я действительно хочу разобраться в этом.

Спасибо за ваши идеи!


person Indigo    schedule 21.03.2018    source источник


Ответы (1)


Насколько я могу судить, это количество итераций в алгоритме ARGON2.

Если вы отследите его через источник PHP, вы получите

https://github.com/php/php-src/blob/master/ext/standard/password.c#L528

который вызывает

https://github.com/P-H-C/phc-winner-argon2/blob/master/src/argon2.c#L67

Итак, здесь t_cost соответствует количеству проходов ^

Также обратите внимание:

См. https://password-hashing.net/submissions/specs/Argon-v3.pdf — 2.1.1 — Входные данные: количество итераций t может быть любым целым числом от 1 до 232 — 1

person Ben Edmunds    schedule 21.03.2018
comment
Ах, конечно, я должен был проверить исходный код! Это глупо с моей стороны. - person Indigo; 21.03.2018
comment
Однако документация PHP делает ее излишне запутанной. Зачем говорить о максимальном количестве времени, когда вы просто говорите об итерациях... - person Indigo; 21.03.2018
comment
К вашему сведению: любой может предложить внести изменения в эти документы через онлайн-редактор документации или запрос на вытягивание. - person salathe; 21.03.2018
comment
Я мог бы сделать это действительно. Тем не менее, я хотел бы получить больше информации о том, почему это было сформулировано именно так... - person Indigo; 21.03.2018
comment
@Indigo - в идеальном сценарии можно было бы измерить время для вычисления одного хэша и установить итерации так, чтобы время вычисления соответствовало максимальному времени, которое вы готовы себе позволить. Чем больше итераций, тем безопаснее, но и больше ресурсов процессора (это зависит от сервера). Конечно, это можно было бы объяснить более понятно. - person martinstoeckli; 22.03.2018
comment
Теперь я понимаю причину этого. Тем не менее, я думаю, что документ PHP должен оставаться ближе к тому, как его представляет спецификация, то есть итерации используются для настройки времени выполнения независимо от выделенной памяти. И, возможно, предлагает несколько советов о том, как найти этот номер, как вы объяснили сами. - person Indigo; 22.03.2018