Навіщо використовувати ключ та секрет API?


93

Я натрапив на багато API, які надають користувачеві як ключ API, так і a секрет . Але моє запитання: яка різниця між ними?

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

То навіщо використовувати дві клавіші?

Редагувати: чи цей ключ API використовується для пошуку секрету API?


Відповіді:


46

Криптографія секретного ключа покладається на використання того самого ключа для кодування, а потім і декодування повідомлення. Таким чином, прочитати повідомлення може лише той, хто знає «таємницю».

Захист RSA базується на 2 відповідних ключах. Для кожного користувача існує відкритий ключ, і кожен може (повинен) його знати. Також є приватний ключ, який повинен знати лише користувач. Повідомлення, зашифроване відкритим ключем, може бути розшифровано лише приватним ключем, і навпаки.

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

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

Ця форма шифрування досить комп’ютерна, тому іноді робиться шифрування одноразового «секретного ключа» за допомогою технології RSA, потім шифрування решти повідомлення секретним ключем, а потім зашифрування мого підпису другим способом. Потім ви відміняєте цей процес, тому якщо повідомлення та підпис читаються, ви і лише ви можете його прочитати, і ви гарантовано надіслали повідомлення.

АБО

Ви можете відвідати це посилання для більш детального пояснення.

Як працюють ключі API та секретні ключі?


9
Хороша відповідь, але коли я використовую секрети API та ключі з Facebook, Gmail тощо, ні в якому разі мені не доводиться нічого шифрувати чи хешувати. У яких випадках сенс секретів та ключів API?
Quintonn

2
Використовуючи Facebook як приклад, є два сценарії, якими ви б застосували app_secret. Перший не вимагає хешування. Він в основному використовується для запобігання викраденню вашої URL-адреси перенаправлення. Після того, як користувач увійде в систему і надасть вашій програмі доступ, якщо facebook надіслав маркер доступу безпосередньо на URL-адресу переадресації, ви не зможете перевірити, чи маркер доступу надходив від Facebook. Я міг би розмістити свій власний маркер доступу до вашої URL-адреси переадресації та виконати дії facebook, які надходили б з вашого API. Натомість facebook надсилає код на адресу переадресації. Потім API обмінює код на фактичний маркер доступу.
Ryan Thomas

2
Під час останньої частини, обмінюючись кодом на фактичний маркер доступу, facebook очікує, що ваш api підтвердить свою особу підписом. У цьому сценарії для підписання їм не потрібна криптографія з відкритим ключем, вони просто довіряють вам зберігати таємницю програми по-справжньому та використовувати її як свій підпис. Мені завжди здавалося безглуздим не використовувати та використовувати односторонню функцію для генерації підпису, але, мабуть, у них є такі причини, як продуктивність для врегулювання безпосереднього використання секрету програми.
Райан Томас,

У другому випадку ви використовуєте криптографічне хешування. Після того, як у вас буде фактичний access_token, щоб почати взаємодіяти з facebook, вам може знадобитися додатковий захист, щоб запобігти видаванню себе за додаток. На консолі програми Facebook ви можете ввімкнути функцію, яка вимагає, щоб кожен запит API-файлу facebook від вашої програми включав ваш підпис на додаток до маркера доступу. Я просто здогадуюсь про їх мотиви, але я думаю, що на даний момент вони не хочуть, щоб ви повторно надсилали app_secret як підпис під кожним запитом. Чим більше ви надсилаєте, тим більша ймовірність компрометації app_secret.
Райан Томас,

1
Я гадаю, оскільки ви вибрали цю додаткову функцію безпеки, ви також прийняли своєрідне рішення, щоб дозволити додаткові накладні витрати на Facebook, перевіряючи ваш підпис криптографічним хеш-викликом на їх кінці. У будь-якому випадку в цьому сценарії ви передаєте два значення із вашими запитами API на Facebook. Token_token та значення appsecret_proof, яке служить вашим підписом. Доказ секрету програми генерується за допомогою криптографічного хешування access_token, використовуючи app_secret як ключ.
Ryan Thomas

55

Вам потрібні дві окремі клавіші, одна, яка повідомляє їм, хто ви є, а друга, яка доводить, що ви такий, яким ви говорите, що є .

"Ключ" - це ваш ідентифікатор користувача, а "секрет" - ваш пароль. Вони просто використовують терміни "ключ" та "секрет", оскільки саме так вони це реалізували.


1
А що, якщо ви спілкуєтесь через https? Який сенс тоді шифрувати своє повідомлення за допомогою якогось секретного ключа?
kamuniaft

6
Справа завжди в тому, щоб зменшити ризик. Якщо комунікація https порушена, зловмисник, який може прочитати ваш запит, не зможе підробити нові. Якщо ваш API збирається ранжувати фотографії котів, нічого
страшного

Я припускаю, що мета - це два окремі ключі, оскільки різні користувачі одного клієнтського додатку можуть мати різні секрети, інакше якщо у всіх буде однаковий секрет, тоді наявність ключа не корисно. Правда?
Мед,

Чому ці API не використовують Bearer:для цього автентифікацію? Ви мали б там посвідчення особи та інвалідність.
Стефан Габерль,

7

Проста відповідь, якщо я правильно зрозумів ...

Якщо ви використовуєте свій ключ API для шифрування, як служба дізнається, хто з ними зв’язується? Як вони розшифрують це повідомлення?

Ви використовуєте API-ключ, щоб вказати, хто ви, це те, що ви надсилаєте звичайним текстом. СЕКРЕТ-ключ нікому не надсилаєте . Ви просто використовуєте його для шифрування. Потім ви надсилаєте зашифроване повідомлення. Ви не надсилаєте ключ, який був використаний для шифрування, щоб переконати мету.


Ти робиш. Ви відправляєте ключ API на сервер. Отже, це означає, що ви надаєте це значення кожному, хто може перехоплювати ваш зв'язок із сервером.
ancajic

Майже в кожному API, який я бачив, ви надсилаєте і ключ, і секрет на сервер. Підключення до сервера зашифровано з теоретично однаковим рівнем безпеки. Але я ніколи не даю нікому, крім сервера.
sudo

Я ніколи не бачив надсилання secretв простому тексті. Чи можете ви дати мені посилання? Побачене я використовую secretдля шифрування деяких даних. А разом із зашифрованими даними надсилання, apiKeyщоб сервер знав, як розшифрувати дані.
ancajic

twilio.com/docs/sms/tutorials/… та nexmo.github.io/Quickstarts/sms/send - це приклади, які я побачив, що спонукало мене до пошуку на StackOverflow.
sudo

Twilio не зовсім використовує ці терміни. Але Nexmo впевнена ... Але, після того, як швидкий погляд, здається , що вони просто телефонують дані secretі apiKeyі то , що вони на насправді роблять це usernameі password. Що зовсім інша річ ...
ancajic

3

Є відповіді, що пояснюють, що таке секретний та (відкритий) ключ. Це пара державно-приватних ключів, якій вони дають заплутані імена. Але ніхто не каже, чому API вимагають обох, і багато API дають вам лише один секрет! Я також ніколи не бачив, щоб будь-які документи API пояснювали, чому вони мають два ключі, тому найкраще, що я можу зробити, це припускати ...

Краще вкласти у свій запит лише свій відкритий ключ і підписати запит локально своїм приватним ключем; надсилати щось більше не потрібно. Але декому вдається лише мати секрет у запиті. Гаразд, будь-який хороший API використовуватиме певну транспортну безпеку, наприклад TLS (зазвичай через HTTPS). Але ви все-таки виставляєте свій приватний ключ серверу таким чином, збільшуючи ризик того, що вони якось неправильно з ним поводяться (див .: нещодавно виявлена ​​помилка реєстрації паролів GitHub та Twitter). І HTTPS теоретично настільки ж безпечний, але в його реалізації завжди є недоліки.

Але багато хто - насправді так здається - API вимагають надсилання обох ключів у запитах, оскільки це простіше, ніж змусити людей робити власні підписи; інакше не може бути прикладів чистого curl! У такому випадку безглуздо розлучати їх між собою. Я думаю, окремі клавіші призначені лише на випадок, якщо вони згодом змінять API, щоб скористатися ними. Або у деяких є клієнтська бібліотека, яка може зробити це більш безпечним способом.


1

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

Якщо ви використовуєте систему, яка використовує "ключ" для пошуку користувача або облікових даних, ця інформація може поступово вгадуватися з часом, надсилаючи тисячі запитів та вивчаючи час, який потрібно вашій базі даних для пошуку (чи ні знайти) запис. Це особливо вірно, якщо "ключ" зберігається у відкритому тексті замість одностороннього хешу ключа. Ви хотіли б зберегти ключі користувачів у відкритому тексті або в симетрично зашифрованому вигляді, якщо вам потрібно мати можливість відображати ключ користувачеві знову.

Отримавши другу інформацію або "секрет", ви можете спочатку шукати користувача або облікові дані за допомогою "ключа", який може бути вразливим до атаки синхронізації, а потім використовувати функцію порівняння, безпечну для синхронізації, щоб перевірити значення секрет".

Ось реалізація цієї функції Python:

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

І це виставляється в hmaclib (і, можливо, інших):

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


Тут слід зауважити одне, що я не думаю, що такий вид атаки буде працювати на значення, які хешуються або шифруються перед пошуком, оскільки значення, які порівнюються, змінюються випадковим чином щоразу, коли змінюється символ у вхідному рядку. Я знайшов гарне пояснення цього тут .

Тоді рішеннями для зберігання ключів API будуть:

  1. Використовуйте окремий ключ і секрет, використовуйте ключ, щоб шукати запис, і використовуйте безпечне порівняння часу, щоб перевірити секрет. Це дозволяє вам знову показати користувачеві ключ і секрет для користувача.
  2. Використовуйте окремий ключ і секрет, використовуйте симетричне, детерміноване шифрування секрету та виконуйте звичайне порівняння зашифрованих секретів. Це дозволяє вам знову показати користувачеві ключ і секрет, і це може позбавити вас від необхідності впроваджувати порівняння, безпечне за часом.
  3. Використовуйте окремий ключ і секрет, відображайте секрет, хеш і зберігайте його, а потім виконайте звичайне порівняння хешованого секрету. Це позбавляє від необхідності використовувати двостороннє шифрування та додає додаткову перевагу збереження вашої таємниці в безпеці, якщо система порушена. Він має мінус у тому, що ви не можете повторно показати секрет користувачеві.
  4. Використовуйте один ключ , один раз покажіть його користувачеві, хеш, а потім виконайте звичайний пошук хешованого або зашифрованого ключа. Тут використовується один ключ, але він не може бути показаний користувачеві знову. Має перевагу захищати ключі, якщо система порушена.
  5. Використовуйте один ключ , один раз покажіть його користувачеві, зашифруйте його та виконайте звичайний пошук зашифрованого секрету. Може бути показаний користувачеві ще раз, але ціною того, що ключі є вразливими, якщо їх система порушена.

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

Крім того, я запрошую будь-яких фактичних експертів з питань безпеки критикувати цю відповідь. Я просто хотів винести це там як черговий пункт обговорення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.