Как всегда, лучший способ защитить ключ - не передавать его.
При этом мы обычно используем схему, где каждый «ключ API» состоит из двух частей: несекретного идентификатора (например, 1234) и секретного ключа (например, байта [64]).
- Если вы выдаете ключ API, храните его (соленый и хэшированный) в себе
база данных сервиса.
- Если вы выдаете учетные записи пользователей (защищенные паролем), сохраните
пароли (соленые и хэшированные) в базе данных вашего сервиса
Теперь, когда потребитель первый получает доступ к вашему API, чтобы подключиться, попросите его
- Отправка параметра "username" ("john.doe" не секрет)
- Отправка параметра «APIkeyID» («1234», не секрет)
и верните ему
- соли из вашей базы данных (в случае, если один из параметров неверен,
просто верните немного повторяемой соли - например.
sha1 (имя пользователя + "notverysecret").
- метка времени сервера
Потребитель должен хранить соль для продолжительности сеанса, чтобы все было быстро и гладко, и он должен рассчитывать и сохранять смещение времени между клиентом и сервером.
Потребитель теперь должен рассчитать соленые хэши API-ключа и пароля. Таким образом, потребитель получает те же хеши для пароля и API-ключа, что и в вашей базе данных, но без каких-либо секретов.
Теперь, когда потребитель впоследствии получает доступ к вашему API, чтобы выполнить реальную работу, попросите его
- Отправка параметра "username" ("john.doe" не секрет)
- Отправка параметра «APIkeyID» («1234», не секрет)
- Отправка параметра "RequestSalt" (байт [64], случайный, не секретный)
- Отправить параметр «RequestTimestamp» (рассчитывается по времени клиента и известному смещению)
- Отправка параметра "RequestToken" (хеш (хеш пароля + запрос_сальта + request_timestamp + apikeyhash))
Сервер не должен принимать временные метки больше, чем, скажем, 2 секунды в прошлом, чтобы обезопасить себя от атаки с повтором.
Сервер теперь может вычислять тот же хеш (passwordhash + request_salt + request_timestamp + apikeyhash), что и клиент, и быть уверенным, что
- клиент знает ключ API,
- клиент знает правильный пароль