Я разрабатываю веб-API, которому необходимо предоставить доступ к различным клиентским приложениям с помощью ключа API, отправленного в виде заголовка http. Я знаю, не совсем так, как это должно быть сделано, но я не контролирую эту часть.
Мой текущий дизайн для ключа API: 16 байтов для идентификатора приложения (guid) в базе данных + 16 байтов, сгенерированных случайным образом (keybytes). Из-за политики компании меня попросили не хранить ключи API в базе данных, поэтому я храню хэш sha256 (clientid + keybytes + соль) и соль в базе данных.
Всякий раз, когда приходит запрос, я разбиваю ключ API на (id, keybytes), ищу клиента в базе данных по id, затем вычисляю sha256 (id + keybytes + salt-from-db) и проверяю, соответствует ли он хэшу, хранящемуся в базе данных. . Требования группы корпоративной безопасности заключались в том, чтобы не хранить ключ API в базе данных, а хранить его хэш (точно так же, как пароль пользователя). Я также рассматривал PBKDF2 (я использую .net 5), но он может быть слишком медленным для выполнения этого при каждом входящем запросе (он должен запускаться для каждого запроса, потому что я не могу изменить клиентские приложения для входа через медленный вызов, а затем отправить токен, они должны просто отправлять ключ с каждым запросом).
По сути, это похоже на хранение sha256 (пароль + соль) в базе данных для пользователя, поэтому я действительно не уверен, что это «достаточно хорошо» (учитывая, что пароль представляет собой случайные 16 байтов, а идентификатор пользователя - еще один случайный 16 байтов - приложение guid и БД теоретически не доступный).
В качестве альтернативы для ключей API у меня есть AES-GCM: сгенерировать случайный одноразовый номер (iv) и зашифровать идентификатор приложения (guid) с помощью секретного ключа (хранится только в настройках webapi, а не в db) и использовать байты (nonce , зашифрованный идентификатор, тег) в качестве ключа API. Это означало бы отсутствие поиска в базе данных в случае неверных ключей API. Я, однако, не уверен, насколько безопасно это решение (в конце концов, я шифрую только один 128-битный блок данных — appid guid — с помощью ключа среди всех клиентов).
Какой из них «приемлем» (если это оба, я возьму первый, поскольку он уже реализован) в случае «нарушения безопасности (например, база данных украдена)?
Я знаю, если они доберутся до бд, ключ апи меня меньше всего беспокоит, но все же хотелось бы услышать мнение....