Я создаю REST API, который использует ключи API для аутентификации. Я хочу убедиться, что эти ключи API надежно хранятся в моей базе данных. Если бы я хранил пароли пользователей, я бы использовал Argon2id для хеширования. Для других типов конфиденциальных пользовательских данных, требующих расшифровки, я бы рассмотрел возможность использования шифрования AES.
Однако я не уверен в том, как лучше всего хранить ключи API. В частности, я хочу знать:
Я просмотрел рекомендации OWASP, но не смог найти однозначных рекомендаций по этой теме.
Ключ API — это пароль. Он имеет характеристики, отличные от типичного человеческого пароля, но представляет собой строку символов, которая позволяет его носителю аутентифицироваться.
Итак, должно быть:
У вас должна быть возможность изменить алгоритм во время развертывания. Я бы использовал длину изображения, чтобы узнать, какой алгоритм использовался, оставив себе в будущем хлопоты по удалению дополнительного неиспользуемого случайного символа, добавленного к изображению, на случай, если вам придется переключиться на алгоритм с такой же выходной длиной.
Эта таблица даст вам представление о времени, которое требуется для подбора ключа API, полученного с помощью bcrypt, на высокопроизводительном оборудовании. Если вы обеспокоены атакой со стороны государства, добавьте несколько символов в свой ключ API.
Тот, кто встретит ключ API, узнает об этом. В вашей системе должна быть конечная точка API, которая будет обменивать временный ключ API (известный администраторам и разработчикам) с реальным ключом API.
Протокол прост:
Вы можете использовать описанный выше механизм для реализации ротации ключа администратором. Они просто заходят, меняют ключ API и все готово. Ключ им не обязательно показывать.
Если вы считаете, что ключ API был скомпрометирован, вы вернетесь к первоначальному процессу регистрации. Администратору будет показан новый ключ API, переданный разработчикам и настроенный в приложении. Его использование вернет код 401, который запустит описанный выше процесс.
+ Если вы, разработчики, можете легко прочитать ключ из рабочей конфигурации, это другая проблема.
Я обеспокоен тем, что выбор Argon2id, учитывая его природу и рекомендуемую конфигурацию (19 МБ памяти, количество итераций 2 и степень параллелизма 1), существенно повлияет на системные ресурсы. Если я правильно понимаю, каждая операция хеширования потребует 19 МБ ОЗУ, то есть 100 одновременных запросов будут потреблять примерно 1,9 ГБ ОЗУ.
Более того, конфигурация со степенью параллелизма 1 и двумя итерациями могла оказать значительную нагрузку на процессор. Моя первоначальная реакция заключалась в том, что эти накладные расходы кажутся чрезмерными и что, возможно, существует лучший компромисс между безопасностью и производительностью. Однако я также признаю, что это может быть принятие желаемого за действительное, и преимущества безопасности могут оправдать затраты на ресурсы. Как однажды сказал мой профессор: «Те, кто предпочитает производительность безопасности, не заслуживают ни того, ни другого».
Извините, я думал, что использование аргона является обязательным требованием. Вы должны подумать о своей модели угроз (кто-то украл вашу базу данных и запустил hashcat
на ваших хэшах. Даже сломанный несоленый MD5 продлится некоторое время, если у вас есть 16 случайных буквенно-цифровых ключей API со смешанным регистром. Используйте соленый SHA2-256 или bcrypt и спите спокойно. + Вот почему вы должны упростить и включить в контракт API возможность изменения ключа API во время выполнения. Я отредактирую свой ответ, включив это.
Спасибо за пояснение. Теперь я понимаю, что не совсем ясно изложил свои требования. Интересно, что вы дали мне еще больше поводов для размышления. Я вижу, что это довольно сложная тема. Предоставить пользователям возможность программно изменять свои собственные ключи API — интригующая идея, которая мне не приходила в голову, но она имеет смысл. Обычно пользователи создают и отзывают ключи API через интерфейс, но управление этим на уровне API упростит интеграцию и уменьшит количество людей, которые увидят ключ API до того, как он будет передан, например, в Vault.
Тем не менее, совместить возможность программного изменения ключа API с понятным механизмом автоматической ротации ключей — отличная идея. Одно замечание для уточнения: в разделе «Крипто-гибкость» вы указываете длину изображения. Я предполагаю, что вы имеете в виду длину строки, в которой сохраняется хешированный пароль.
Да. Я предпочитаю это слово вместо «хеш», потому что помимо хэшей существуют и другие односторонние функции.
Моя проблема возникает именно по этой причине: ключи API используются в качестве паролей и имеют некоторые общие характеристики, но они не совпадают. Я понимаю использование Argon2id для хеширования паролей из-за низкого качества и энтропии типичных паролей, выбираемых пользователем. Однако ключи API часто используются по-другому. Хотя пароли обычно используются для установления сеанса для последующих запросов, ключи API проверяются при каждом запросе, то есть процесс аутентификации выполняется неоднократно.