Як захистити API REST лише для надійних мобільних додатків


96

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

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

Чи є спосіб досягти цього?

Оновлення: Користувач може виконувати дії лише для читання, які не вимагають входу користувача, але вони також можуть виконувати дії запису, які вимагають входу користувача (Authentication by Access Token). В обох випадках я хочу, щоб API відповідав на запити, що надходять лише від надійних мобільних додатків.

API також використовуватиметься для реєстрації нового облікового запису через мобільний додаток.

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


HTTPS використовує SSL (і TLS). SSL / TLS можна використовувати з аутентифікацією клієнта.
atk

Ви маєте на увазі клієнтські сертифікати SSL? Я думаю, що це те, що я шукаю, за винятком поняття, що це можливо навіть у мобільних додатках (Android та iOS)? Де зберігався б сертифікат клієнта? Зберігання пристрою, пам'ять?
Суперклей

SSL сертифікуватиме лише мобільний пристрій, а не мобільний додаток.
Морон

@Supercell: Я додам відповідь
atk

Відповіді:


48

Ви не можете.

Ніколи не можна перевірити суб'єкт господарювання, будь-яку організацію , будь то особа, клієнт апаратного забезпечення або клієнт програмного забезпечення. Ви можете лише переконатися, що те, що вони вам говорять , є правильним, а потім припустити чесність .

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

Це точно те саме, що перевіряє Клієнта. Ви можете лише підтвердити поведінку Клієнта, але не самого Клієнта.

Таким чином, за допомогою SSL ви можете перевірити, чи має клієнт дійсний сертифікат чи ні. Отже, ви можете просто встановити додаток, отримати Cert, а потім запустити весь новий код.

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

Також дивіться: Перемогу перевірки SSL-сертифіката для додатків Android

та: Наскільки безпечні сертифікати SSL клієнта в мобільному додатку?


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

1
@Morons: webapp вирішить це, але ми вважаємо, що користувачі будуть скоріше використовувати нативну програму, ніж webapp (будь ласка, виправте мене, якщо наше припущення неправильне). Причина, чому це так важливо, полягає в тому, що API надає користувачеві доступ до частин нашої бази даних, які містять багато даних, які ми зібрали за місяці роботи. Це дані, які інші компанії або користувачі могли легко використовувати для власних цілей. Без забезпечення клієнтів ми б не знали, хто ним користується (проти нас).
Supercell

6
Вебапп не вирішує питання. Досить тривіально змінити будь-яку сторону клієнта веб-сайту і змусити її робити все, що завгодно.
Стівен Бернап

5
@Supercell Ви не можете показувати комусь дані, а потім не дозволяєте їм їх обмінюватися. Якщо ви не хочете, щоб деякі мали дані, ви не надаєте їх (показуйте).
Морон

Я згоден, але з іншої причини. Ви начебто можете, якщо у вас був контроль над пристроями, rsa схожа на en.wikipedia.org/wiki/SecurID . Але мобільні телефони - це не те, чим можна керувати (вони можуть прийняти вкладення, як ключ плагіна чи щось таке).
име96

31

Я впевнений, що вам зручно працювати з входами користувачів та спілкуванням через SSL, тому я сфокусуюсь на тому, що, на мою думку, більш цікавій частині питання: як забезпечити ваші дії лише для читання - у яких НЕ потрібно користувачеві для аутентифікації - приймаються тільки від ваших власних додатків клієнта?

Перш за все, є мінус, на який fNek натякав у попередній відповіді - ваші клієнтські програми знаходяться в руках потенційно ворожих користувачів. Їх можна оглянути, перевірити їх зв’язок, розібрати код. Ніщо, що я збираюся запропонувати, не дозволить вам гарантувати, що хтось не реінжиніринг вашого клієнта і не зловживатиме вашим REST API. Але це повинно поставити бар'єр перед будь-якими випадковими спробами.

У будь-якому випадку загальним підходом є:

  • Клієнт містить секрет
  • Здійснюючи запит, він поєднує параметри запиту із секретами та хеширує результат
  • Цей хеш надсилається із запитом та перевіряється сервером

наприклад, уявіть собі GETзапит/products/widgets

Скажімо, секрет клієнта - "OH_HAI_I_IZ_SECRET"

Об'єднайте дієслово HTTP, URL та секрет:

GET/products/widgetsOH_HAI_I_IZ_SECRET

І візьміть хеш -код SHA-1 :

4156023ce06aff06777bef3ecaf6d7fdb6ca4e02

Потім надішліть це разом, щоб запит був для:

GET /products/widgets?hash=4156023ce06aff06777bef3ecaf6d7fdb6ca4e02

Нарешті, щоб не допустити, щоб хтось принаймні відтворював окремі запити, візьміть також часову позначку та додайте її до параметрів та хешу. наприклад, зараз, в Unix час, це 1384987891. Додайте це до конкатенації:

GET/products/widgetsOH_HAI_I_IZ_SECRET1384987891

Хеши, що:

2774561d4e9eb37994d6d71e4f396b85af6cacd1

І надішліть:

GET /products/widgets?time=1384987891&hash=2774561d4e9eb37994d6d71e4f396b85af6cacd1

Сервер перевірить хеш, а також перевірить, чи часова мітка поточна (наприклад, протягом 5 хвилин, щоб годинники не синхронізувались ідеально)

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


6
цей механізм хешування може бути зрозумілий будь-якому програмісту, коли він розбирає apk.
Punith Raj

8
@PunithRaj точно, я висвітлював це у другому абзаці. "Ніщо, що я збираюся запропонувати, не дозволить вам гарантувати, що хтось не реінжиніринг вашого клієнта і не зловживатиме вашим REST API. Але це повинно поставити бар'єр перед будь-якими випадковими спробами."
Carson63000

для попередження, я використовую UTC на сервері та мобільному, це вирішує проблему, правда?
shareef

@ Carson63000 - значить, чи є конкретне рішення? особливо для API реєстрації користувачів, який повинен бути відкрито відкритим (користувачеві потрібно зареєструватися, перш ніж він зможе увійти, або в Інтернеті, або в мобільному додатку), і його можуть націлити боти, щоб створити тисячі підроблених користувачів.
Тохід

17

Для всіх, хто цікавиться, на ОС Android ви можете переконатися, що отриманий вами запит було надіслано з вашої програми.

Коротше кажучи, коли ви завантажуєте свою програму в Google, ви підписуєте її за допомогою унікального ключа, відомого лише вам (і Google).

Процес перевірки проходить (ish) так:

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

повний блог, який пояснює це та як його реалізувати, можна знайти тут: http://android-developers.blogspot.co.il/2013/01/verifying-back-end-calls-from-android.html


1
Хороша відповідь, однак шкідливий користувач може все-таки підробити додаток при достатній кількості зусиль. але нічого не справді безпечне, справа не в тому, а лише в тому, коли
матеос

1
Для iOS існує такий варіант: посилання API DeviceCheck також дозволяє переконатися, що отриманий маркер надходить з автентичного пристрою Apple, на який було завантажено ваш додаток
Iwaz

Тут потрібні акаунти (електронні листи)
користувач25

5

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

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


5

Як згадував @Morons у своїй відповіді, дуже важко перевірити сутність на іншому кінці з'єднання.

Найпростіший спосіб надати певний рівень автентичності - це змусити сервер перевірити якийсь секрет, який би знав лише реальний суб'єкт. Для користувача це можуть бути ім’я користувача та пароль. Для програмного забезпечення, де немає користувача, ви можете вкласти секрет.

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

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

Я працюю в компанії під назвою CriticalBlue (Повне розкриття!), Яка має продукт під назвою Approov, який намагається вирішити цю проблему довіри. Наразі він працює для Android / iOS і забезпечує механізм для наших серверів для перевірки цілісності клієнтської програми. Це робиться шляхом отримання клієнтом розрахунку відповіді на випадковий виклик. Клієнт повинен обчислити відповідь, використовуючи атрибути встановленого пакету додатків, які важко підробити, і він включає деякі складні механізми боротьби з підробкою.

Він повертає маркер, який ви можете потім надіслати як підтвердження автентичності до свого API.

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

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


0

SSL забезпечить канал зв'язку.

Успішний логін видасть маркер автентифікації для зашифрованого з'єднання.

Маркер автентифікації буде переданий вашому API REST у всіх наступних запитах.


1
Я додав додаткову інформацію. Я планував зробити аутентифікацію, як ви згадали, з маркером доступу. API REST не вимагає входу користувача лише для конкретних дій. В обох випадках клієнтів потрібно підписати / довірити.
Суперклей

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

Це може спрацювати, але це вимагатиме від користувача увійти та вказати номер облікового запису користувача. В іншому випадку сервер не матиме нічого для підтвердження номера.
Суперклей

Як ви збираєтесь встановити свій мобільний додаток?
CodeART

Вони будуть доступні через магазини додатків (Google, Apple, Microsoft)
Supercell

0

Це було б не надто безпечно, але ви можете додати якийсь секретний код або навіть dgital підпис. Знизу: він повинен бути включений у додаток, що дозволяє легко отримати його, якщо ви знаєте, чим займаєтесь.


0

Наскільки я знаю, HTTPS полягає лише в тому, щоб перевірити сервер, з яким ви спілкуєтесь, хто це говорить.

Насправді ви можете використовувати SSL для аутентифікації як клієнта, так і сервера. Або, сказано інакше, "так, ви можете використовувати клієнтські сертифікати".

Вам потрібно буде ...

  • перегляньте бібліотеку SSL, яку ви використовуєте, щоб визначити, як вказати клієнтські сертифікати на мобільному пристрої,
  • написати код або налаштувати ваш сервер HTTPS так, щоб він приймав з'єднання лише від надійних зареєстрованих клієнтів.
  • придумайте механізм додавання довірених клієнтських сертифікатів на ваш сервер
  • придумайте механізм для видалення більше не надійних сертифікатів клієнта з вашого сервера

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

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