Как безопасно хранить ключи API в базе данных для REST API?

Я создаю REST API, который использует ключи API для аутентификации. Я хочу убедиться, что эти ключи API надежно хранятся в моей базе данных. Если бы я хранил пароли пользователей, я бы использовал Argon2id для хеширования. Для других типов конфиденциальных пользовательских данных, требующих расшифровки, я бы рассмотрел возможность использования шифрования AES.

Однако я не уверен в том, как лучше всего хранить ключи API. В частности, я хочу знать:

  1. Должен ли я хешировать ключи API перед сохранением их в базе данных, подобно паролям пользователей?
  2. Если рекомендуется хеширование, какие алгоритмы лучше всего подходят для этой цели?
  3. Существуют ли какие-либо конкретные соображения или рекомендации по безопасному хранению и управлению ключами API, которые отличаются от обработки паролей или других конфиденциальных данных?

Я просмотрел рекомендации OWASP, но не смог найти однозначных рекомендаций по этой теме.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
175
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ключ API — это пароль. Он имеет характеристики, отличные от типичного человеческого пароля, но представляет собой строку символов, которая позволяет его носителю аутентифицироваться.

Итак, должно быть:

  1. Полностью случайный, не полученный из идентификатора учетной записи или любого другого идентификатора.
  2. Хранится с использованием односторонней функции Argon2id с рекомендуемыми параметрами вполне подходит, но популярным выбором являются bcrypt и соленый SHA2-256.
  3. Автоматическая ротация ключа API при первом использовании
  4. Администратор может изменить ключ API в случае компрометации.
  5. Можно изменить односторонний алгоритм во время развертывания. Сохранение используемого алгоритма — один из способов сделать это, но вам может сойти с рук вывод алгоритма на основе длины сохраненного вами одностороннего изображения.

Крипто-гибкость

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

Эта таблица даст вам представление о времени, которое требуется для подбора ключа API, полученного с помощью bcrypt, на высокопроизводительном оборудовании. Если вы обеспокоены атакой со стороны государства, добавьте несколько символов в свой ключ API.

Автоматическое вращение

Тот, кто встретит ключ API, узнает об этом. В вашей системе должна быть конечная точка API, которая будет обменивать временный ключ API (известный администраторам и разработчикам) с реальным ключом API.

Протокол прост:

  1. Когда выполняется вызов API с API, который необходимо изменить, вы возвращаете код ошибки 401.
  2. В приложении есть логика для обработки ошибки путем вызова API «обновить ключ».
  3. Приложение получает новый ключ API и сохраняет его без вмешательства человека.
  4. Вызов API повторяется.

Изменить ключ API в случае компрометации

Вы можете использовать описанный выше механизм для реализации ротации ключа администратором. Они просто заходят, меняют ключ API и все готово. Ключ им не обязательно показывать.

Если вы считаете, что ключ API был скомпрометирован, вы вернетесь к первоначальному процессу регистрации. Администратору будет показан новый ключ API, переданный разработчикам и настроенный в приложении. Его использование вернет код 401, который запустит описанный выше процесс.

+ Если вы, разработчики, можете легко прочитать ключ из рабочей конфигурации, это другая проблема.

Моя проблема возникает именно по этой причине: ключи API используются в качестве паролей и имеют некоторые общие характеристики, но они не совпадают. Я понимаю использование Argon2id для хеширования паролей из-за низкого качества и энтропии типичных паролей, выбираемых пользователем. Однако ключи API часто используются по-другому. Хотя пароли обычно используются для установления сеанса для последующих запросов, ключи API проверяются при каждом запросе, то есть процесс аутентификации выполняется неоднократно.

lmmendes 05.06.2024 23:48

Я обеспокоен тем, что выбор Argon2id, учитывая его природу и рекомендуемую конфигурацию (19 МБ памяти, количество итераций 2 и степень параллелизма 1), существенно повлияет на системные ресурсы. Если я правильно понимаю, каждая операция хеширования потребует 19 МБ ОЗУ, то есть 100 одновременных запросов будут потреблять примерно 1,9 ГБ ОЗУ.

lmmendes 05.06.2024 23:48

Более того, конфигурация со степенью параллелизма 1 и двумя итерациями могла оказать значительную нагрузку на процессор. Моя первоначальная реакция заключалась в том, что эти накладные расходы кажутся чрезмерными и что, возможно, существует лучший компромисс между безопасностью и производительностью. Однако я также признаю, что это может быть принятие желаемого за действительное, и преимущества безопасности могут оправдать затраты на ресурсы. Как однажды сказал мой профессор: «Те, кто предпочитает производительность безопасности, не заслуживают ни того, ни другого».

lmmendes 05.06.2024 23:48

Извините, я думал, что использование аргона является обязательным требованием. Вы должны подумать о своей модели угроз (кто-то украл вашу базу данных и запустил hashcat на ваших хэшах. Даже сломанный несоленый MD5 продлится некоторое время, если у вас есть 16 случайных буквенно-цифровых ключей API со смешанным регистром. Используйте соленый SHA2-256 или bcrypt и спите спокойно. + Вот почему вы должны упростить и включить в контракт API возможность изменения ключа API во время выполнения. Я отредактирую свой ответ, включив это.

ixe013 06.06.2024 04:03

Спасибо за пояснение. Теперь я понимаю, что не совсем ясно изложил свои требования. Интересно, что вы дали мне еще больше поводов для размышления. Я вижу, что это довольно сложная тема. Предоставить пользователям возможность программно изменять свои собственные ключи API — интригующая идея, которая мне не приходила в голову, но она имеет смысл. Обычно пользователи создают и отзывают ключи API через интерфейс, но управление этим на уровне API упростит интеграцию и уменьшит количество людей, которые увидят ключ API до того, как он будет передан, например, в Vault.

lmmendes 06.06.2024 08:46

Тем не менее, совместить возможность программного изменения ключа API с понятным механизмом автоматической ротации ключей — отличная идея. Одно замечание для уточнения: в разделе «Крипто-гибкость» вы указываете длину изображения. Я предполагаю, что вы имеете в виду длину строки, в которой сохраняется хешированный пароль.

lmmendes 06.06.2024 08:46

Да. Я предпочитаю это слово вместо «хеш», потому что помимо хэшей существуют и другие односторонние функции.

ixe013 07.06.2024 04:51

Другие вопросы по теме