Зачем использовать ключ и секрет API?

Я встречал множество API, которые предоставляют пользователю как ключ, так и секрет. Но мой вопрос: в чем разница между ними?

На мой взгляд, одного ключа может хватить. Скажем, у меня есть ключ, который знают только я и сервер. Я создаю хеш HMAC с этим ключом и выполняю вызов API. На сервере мы снова создаем хеш HMAC и сравниваем его с отправленным хешем. Если это то же самое, вызов аутентифицируется.

Так зачем использовать два ключа?

Изменить: или этот ключ API используется для поиска секрета API?


person EsTeGe    schedule 19.07.2012    source источник
comment
Также см. Рекомендации по управлению доступом к AWS Ключи   -  person Honey    schedule 24.07.2019


Ответы (5)


Криптография с секретным ключом основана на использовании одного и того же ключа для кодирования и последующего декодирования сообщения. Таким образом, только те, кто знает секрет, могут прочитать сообщение.

Безопасность RSA основана на 2 совпадающих ключах. У каждого пользователя есть открытый ключ, и каждый может (должен) его знать. Также существует закрытый ключ, который должен знать только пользователь. Сообщение, зашифрованное открытым ключом, может быть расшифровано только закрытым ключом, и наоборот.

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

Или, если я хочу доказать вам, что отправил сообщение, я могу зашифровать сообщение своим закрытым ключом, рассказать вам (в открытом тексте или в другом сообщении), как оно было зашифровано. Затем вы можете расшифровать сообщение с помощью моего открытого ключа, и если оно станет читаемым, вы знаете, что оно пришло от меня.

Эта форма шифрования требует значительных ресурсов компьютера, поэтому иногда используется одноразовый секретный ключ для шифрования с помощью технологии RSA, затем шифруется остальная часть сообщения секретным ключом, а затем моя подпись шифруется вторым способом. Затем вы обращаете этот процесс в обратном порядке, чтобы, если сообщение и подпись доступны для чтения, вы и только вы можете их прочитать, и вы можете быть уверены, что я отправил сообщение.

OR

вы можете посетить эту ссылку для более подробного объяснения.

Как работают ключи API и секретные ключи?

person SALMAN    schedule 19.07.2012
comment
Хороший ответ, но когда я использую секреты и ключи API с Facebook, Gmail и т. Д., Мне ни в коем случае не нужно шифровать или хешировать что-либо. В чем тогда смысл секретов и ключей API? - person Quintonn; 11.07.2016
comment
Используя Facebook в качестве примера, вы можете использовать app_secret в двух сценариях. Первый не требует хеширования. В основном он используется для предотвращения взлома вашего URL-адреса перенаправления. После того, как пользователь войдет в систему и предоставит вашему приложению доступ, если facebook отправил токен доступа непосредственно на URL-адрес перенаправления, у вас не будет возможности проверить, был ли токен доступа от Facebook. Я мог бы опубликовать свой собственный токен доступа к вашему URL-адресу перенаправления и выполнить действия facebook, которые будут исходить из вашего api. Вместо этого facebook отправляет код на URL-адрес перенаправления. Затем api обменивает код на фактический токен доступа. - person Ryan Thomas; 17.02.2017
comment
Во второй части, обменивая код на фактический токен доступа, facebook ожидает, что ваш api подтвердит его личность с помощью подписи. В этом сценарии им не требуется криптография с открытым ключом для подписи, они просто доверяют вам хранить секрет своего приложения в истинном секрете и использовать его в качестве своей подписи. Мне всегда казалось глупым не пойти дальше и не использовать одностороннюю функцию для генерации подписи, но я полагаю, что у них есть причины, такие как производительность, для прямого использования секрета приложения. - person Ryan Thomas; 17.02.2017
comment
Во втором случае вы используете криптографическое хеширование. После того, как у вас будет фактический access_token для начала взаимодействия с facebook, вам может потребоваться дополнительная безопасность, чтобы предотвратить олицетворение вашего приложения. В консоли приложения Facebook вы можете включить функцию, которая требует, чтобы каждый запрос API facebook из вашего приложения включал вашу подпись в дополнение к токену доступа. Я просто догадываюсь об их мотивах, но думаю, что на данный момент они не хотят, чтобы вы многократно отправляли app_secret в качестве подписи при каждом запросе. Чем больше вы отправляете, тем больше вероятность взлома app_secret. - person Ryan Thomas; 17.02.2017
comment
Я полагаю, поскольку вы выбрали эту дополнительную функцию безопасности, вы также приняли своего рода решение разрешить дополнительные накладные расходы на производительность Facebook, проверяя вашу подпись с помощью криптографического хеш-вызова на своей стороне. В любом случае в этом сценарии вы передаете два значения с вашими запросами API Facebook. Access_token и значение с именем appsecret_proof, которое служит вашей подписью. Доказательство секретности приложения генерируется криптографическим хешированием access_token с использованием app_secret в качестве ключа. - person Ryan Thomas; 17.02.2017
comment
Существует множество API, которые дают вам только одно секретное значение. - person sudo; 10.05.2018
comment
Я удивлен, что этот ответ был выбран в качестве принятого ответа. Вопрос касается ключей API и секретных ключей, которые, я не думаю, имеют какое-либо отношение к криптографии или шифрованию с открытым ключом. Ответ Маркуса Адамса - это действительно ответ на этот вопрос. - person mavili; 27.08.2018
comment
Неверное употребление. Открытый ключ можно рассматривать как открытую блокировку. Сайт блокирует сообщение о том, что замок закрывается, и только у вас есть секретный ключ, чтобы открыть его. Когда они генерируют пару, они сохраняют блокировку (открытый ключ) и отправляют вам только секретный ключ. - person gseattle; 12.03.2019
comment
во втором способе. Что это такое? - person Honey; 29.06.2019
comment
@RyanThomas, было бы здорово, если бы вы вложили это в какой-нибудь ответ. Или даже извлеките вопрос из комментария и добавьте на него свой ответ. Никогда не знаешь, что будет с комментариями ... - person Honey; 30.06.2019
comment
Как это принятый ответ. Вопрос и этот ответ не говорят об одном и том же! OP спрашивает о ключах API, а не о криптографических ключах. Я удивлен, что этот ответ был принят как правильный. Ответ от @Marcus Adams ниже должен быть правильным. - person mavili; 16.05.2020

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

«Ключ» - это ваш идентификатор пользователя, а «секрет» - это ваш пароль. Они просто используют термины «ключ» и «секрет», потому что именно так они это реализовали.

person Marcus Adams    schedule 19.07.2012
comment
А что, если вы общаетесь по https? Какой тогда смысл шифровать ваше сообщение каким-то секретным ключом? - person kamuniaft; 12.01.2018
comment
Дело всегда в том, чтобы снизить риск. Если соединение https скомпрометировано, злоумышленник, который сможет прочитать ваш запрос, не сможет подделать новые. Если ваш API собирается ранжировать изображения кошек, ничего страшного, если это платежный API, вам лучше иметь несколько уровней безопасности :) - person Yall; 23.11.2018
comment
Я предполагаю, что это два отдельных ключа, потому что разные пользователи одного клиентского приложения могут иметь разные секреты, в противном случае, если бы у них был один и тот же секрет, то ключ не был бы полезен. Верно? - person Honey; 24.07.2019
comment
Почему этот API не использует для этого Bearer: аутентификацию? У вас там будет идентификатор и пароль. - person Stefan Haberl; 15.05.2020

Простой ответ, если я правильно понял ...

Если вы используете свой ключ API для шифрования, как служба узнает, кто с ними обращается? Как они расшифруют это сообщение?

Вы используете ключ API, чтобы указать, кто вы, это то, что вы отправляете в виде обычного текста. СЕКРЕТНЫЙ ключ, который вы никому не отправляете. Вы просто используете его для шифрования. Затем вы отправляете зашифрованное сообщение. Вы не отправляете ключ, который использовался для шифрования, это нарушило бы цель.

person ancajic    schedule 30.12.2017
comment
Ты сделаешь. Вы отправляете ключ api на сервер. Итак, это означает, что вы придаете эту ценность любому, кто может перехватить ваше общение с сервером. - person ancajic; 11.05.2018
comment
Почти в каждом API, который я видел, вы отправляете на сервер и ключ, и секрет. Соединение с сервером зашифровано с теоретически таким же уровнем безопасности. Но я никогда не отдаю никому, кроме сервера. - person sudo; 11.05.2018
comment
Я никогда не видел отправки secret в виде обычного текста. Можете дать ссылку? Я видел, как используется secret для шифрования некоторых данных. И вместе с зашифрованными данными отправляем apiKey, чтобы сервер знал, как их расшифровать. - person ancajic; 11.05.2018
comment
twilio.com/docs/ sms / tutorials / и nexmo.github.io/Quickstarts/sms/send - это примеры, которые я видел, побудившие меня искать в StackOverflow. - person sudo; 11.05.2018
comment
Twilio не совсем использует эти термины. Но Nexmo уверен ... Но после беглого взгляда кажется, что они просто вызывают данные secret и apiKey, а на самом деле они делают username и password. Что совсем другое ... - person ancajic; 11.05.2018

Есть ответы, объясняющие, что такое секретный и (открытый) ключ. Это пара открытого и закрытого ключей, которой они дают запутанные имена. Но никто не говорит, почему API требуют и того, и другого, а многие API дают вам только один секрет! Я также никогда не видел, чтобы документы API объясняли, почему у них два ключа, поэтому лучшее, что я могу сделать, это предположить ...

Лучше всего указать в запросе только свой открытый ключ и подписать его локально своим закрытым ключом; посылать больше ничего не нужно. Но некоторым удается просто раскрыть секрет в запросе. Хорошо, любой хороший API будет использовать некоторую транспортную безопасность, такую ​​как TLS (обычно через HTTPS). Но вы по-прежнему предоставляете свой закрытый ключ серверу таким образом, увеличивая риск того, что он каким-то образом неправильно его обработает (см. Недавно обнаруженная ошибка регистрации паролей в GitHub и Twitter). И HTTPS теоретически так же безопасен, но всегда есть недостатки в реализации.

Но во многих - на самом деле, кажется, в большинстве - API вы отправляете оба ключа в запросах, поскольку это проще, чем заставлять людей делать свои собственные подписи; иначе не может быть чистых примеров cURL! В таком случае бессмысленно разделять их. Я предполагаю, что отдельные ключи предназначены только на тот случай, если они позже изменят API, чтобы воспользоваться ими. Или у некоторых есть клиентская библиотека, которая может сделать это более безопасным способом.

person sudo    schedule 10.05.2018

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

Если вы используете систему, которая использует «ключ» для поиска пользователя или учетных данных, эту информацию можно постепенно угадывать с течением времени, отправляя тысячи запросов и проверяя время, которое требуется вашей базе данных, чтобы найти (или нет найти) запись. Это особенно верно, если «ключ» хранится в виде открытого текста вместо одностороннего хеширования ключа. Вы хотели бы хранить ключи пользователей в виде открытого текста или симметрично зашифрованные, если вам нужно снова отобразить ключ пользователю.

Имея вторую часть информации или «секрет», вы можете сначала найти пользователя или учетные данные с помощью «ключа», который может быть уязвим для временной атаки, а затем использовать безопасную по времени функцию сравнения, чтобы проверить значение секрет".

Вот реализация этой функции в Python:

https://github.com/python/cpython/blob/cd8295ff758891f21084a6a5ad3403d35dda38f7/Modules/_operator.c#L727

И он представлен в hmac lib (и, возможно, в других):

https://docs.python.org/3/library/hmac.html#hmac.compare_digest


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

Тогда решениями для хранения ключей API будут:

  1. Используйте отдельный ключ и секрет, используйте ключ для поиска записи и используйте безопасное по времени сравнение, чтобы проверить секрет. Это позволяет вам снова показать пользователю ключ и секрет.
  2. Используйте отдельный ключ и секрет, используйте симметричное детерминированное шифрование секрета и выполните обычное сравнение зашифрованных секретов. Это позволяет вам снова показать пользователю ключ и секрет и избавить вас от необходимости выполнять безопасное по времени сравнение.
  3. Используйте отдельный ключ и секрет, отобразите секрет, хэш и сохраните его, а затем выполните обычное сравнение хешированного секрета. Это избавляет от необходимости использовать двустороннее шифрование и дает дополнительное преимущество в виде сохранения секрета в безопасности в случае взлома системы. У него есть обратная сторона: вы не можете снова показать секрет пользователю.
  4. Используйте единый ключ, покажите его пользователю один раз, хешируйте его, а затем выполните обычный поиск хешированного или зашифрованного ключа. Здесь используется один ключ, но он не может быть снова показан пользователю. Имеет преимущество хранения ключей в безопасности, если система скомпрометирована.
  5. Используйте единый ключ, покажите его пользователю один раз, зашифруйте его и выполните обычный поиск зашифрованного секрета. Может быть снова показан пользователю, но за счет уязвимости ключей в случае взлома системы.

Из них я считаю, что 3 - лучший баланс безопасности и удобства. Я видел, как это реализовано на многих веб-сайтах при выдаче ключей.

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

person kbuilds    schedule 07.05.2020