Як надійно зберігати маркер доступу та секрет в Android?


123

Я буду використовувати oAuth для отримання пошти та контактів з Google. Я не хочу просити користувача кожного разу входити, щоб отримати маркер доступу та секрет. З того, що я зрозумів, мені потрібно зберігати їх зі своїм додатком або в базі даних, або SharedPreferences. Але я з цим трохи переживаю аспекти безпеки. Я читав, що ви можете зашифрувати та розшифрувати жетони, але зловмиснику легко декомпілювати ваші apk та класи та отримати ключ шифрування.
Який найкращий спосіб безпечно зберігати ці маркери в Android?


1
Як я зберігаю споживчий ключ та секрет (тверда обкладинка їх не захищена)? Мені потрібні вони, щоб запитувати доступ до секрету та секрет. Як це роблять інші існуючі програми, що використовують oauth? Хм, нарешті, з oauth, вам потрібно подбати про набагато більше питань безпеки для мене .... Мені потрібно тримати ток / секрет споживача надійно, а також доступ до доступу та секрет .... нарешті, чи не було б простіше просто збережіть зашифровані ім’я користувача / пароль? ... Зрештою, чи не останнє краще? Я просто досі не бачу, як оауть краще ...
Так,

Ви можете мені сказати ... який файл зберігає маркер доступу ?? Я новачок в android, і я спробував запустити зразок Plus app. Але я не знайду цього ніде [метод GoogleAuthUtil.getToken ().]
Абхішек Каушик

Відповіді:


117

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

Є кілька переваг зберігання жетонів замість фактичного пароля користувача:

  • Сторонні програми не повинні знати пароль, і користувач може бути впевнений, що він надсилає його лише на оригінальний сайт (Facebook, Twitter, Gmail тощо)
  • Навіть якщо хтось викраде маркер, він не побачить пароль (який користувач може використовувати і на інших сайтах)
  • Маркери зазвичай мають термін експлуатації та закінчуються через певний час
  • Токени можуть бути відкликані, якщо ви підозрюєте, що вони були порушені

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

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

1
@NikolayElenkov: Ви написали "Що стосується шифрування, вам потрібно або вимагати від користувача кожного разу вводити парольну фразу дешифрування (тим самим перемагаючи мету кешування даних), або зберігати ключ до файлу, і ви отримуєте ту ж проблему". . Що робити, якщо сухарики скасують вашу програму, щоб зрозуміти, як працює шифрування? Ваш захист може бути зламаний. Чи є найкращою практикою зберігати таку інформацію (маркер, шифрування ...), використовуючи нативний код?
anhldbk

1
Якщо дані програми видаляються, то маркер оновлення втрачається, що, мабуть, не те, що хотів користувач.
rds

1
Це не найкращий спосіб зберігати жетони вже зараз-у-дні!
Рахул Растогі

19

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

введіть тут опис зображення

Ось офіційне визначення:

Цей клас забезпечує доступ до централізованого реєстру онлайн-акаунтів користувача. Користувач вводить облікові дані (ім’я користувача та пароль) один раз для облікового запису, надаючи додаткам доступ до онлайн-ресурсів із схваленням "одним клацанням".

Детальний посібник із використання AccountManager:

Однак врешті-решт AccountManager зберігає ваш маркер лише як звичайний текст. Отже, я б запропонував зашифрувати ваші секрети, перш ніж зберігати їх у AccountManager. Ви можете використовувати різні бібліотеки шифрування, наприклад AESCrypt або AESCrypto

Інший варіант - використовувати бібліотеку Conceal . Це досить безпечно для Facebook і набагато простіше у використанні, ніж AccountManager. Ось фрагмент коду, щоб зберегти секретний файл за допомогою Conceal.

byte[] cipherText = crypto.encrypt(plainText);
byte[] plainText = crypto.decrypt(cipherText);

2
Хороша порада, що Conceal Виглядає дуже просто у використанні. І для багатьох випадків використання.
Лагос

Не вдалося знайти Conceal за посиланням. Це може бути відключено
user1114

10

SharedPreferences не є безпечним місцеположенням. На вкоріненому пристрої ми легко можемо читати та змінювати всі програми "SharedPrefereces xml. Тож жетони мають закінчуватися відносно часто. Але навіть якщо маркер закінчується щогодини, нові токени все одно можуть бути викрадені з SharedPreferences. Android KeyStore слід використовувати для тривалого зберігання та пошуку криптографічних ключів, які будуть використовуватися для шифрування наших жетонів для їх зберігання, наприклад, SharedPreferences або бази даних. Ключі не зберігаються в процесі роботи програми, тому їх важче порушити.

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


9
Тоді де ми можемо їх зберігати?
Milind Mevada

2
  1. На панелі проектів Android Studio виберіть "Файли проектів" та створіть новий файл під назвою "keystore.properties" у кореневому каталозі вашого проекту.

введіть тут опис зображення

  1. Відкрийте файл "keystore.properties" і збережіть у ньому файл Token та Secret.

введіть тут опис зображення

  1. Тепер завантажте прочитаний маркер доступу та секрет у файл build.gradle модуля додатка . Тоді вам потрібно визначити змінну BuildConfig для Access Token and Secret, щоб ви могли безпосередньо отримати доступ до них зі свого коду. Ваша build.gradle може виглядати наступним чином:

    ... ... ... 
    
    android {
        compileSdkVersion 26
    
        // Load values from keystore.properties file
        def keystorePropertiesFile = rootProject.file("keystore.properties")
        def keystoreProperties = new Properties()
        keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
    
        defaultConfig {
            applicationId "com.yourdomain.appname"
            minSdkVersion 16
            targetSdkVersion 26
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    
            // Create BuildConfig variables
            buildConfigField "String", "ACCESS_TOKEN", keystoreProperties["ACCESS_TOKEN"]
            buildConfigField "String", "SECRET", keystoreProperties["SECRET"]
        }
    }
  2. Ви можете використовувати маркер доступу та секрет у своєму коді так:

    String accessToken = BuildConfig.ACCESS_TOKEN;
    String secret = BuildConfig.SECRET;

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


1
Схоже, немає різниці, що створення файлу властивостей замість жорсткого кодування.
Джошен

Я хочу написати токен під час виконання, моє маркер буде щоразу змінюватися, коли я відкриваю свою програму.
Рехан Сарвар

1
Це дуже хороший спосіб зберігати деякі лексеми, наприклад маркери доступу API. якщо ви хочете зберігати облікові дані користувачів, NDK - це кращий спосіб.
Ерік

7
Це абсолютно не так, як вам слід займатися зберіганням конфіденційної інформації у вашій заявці! Навіть якщо сховище не містить даних за допомогою цього підходу (дані вводяться в процес збирання), це генерує файл BuildConfig, який має маркер / секрет у простому тексті, щоб усі бачили після простого декомпіляції.
Графн

-1

Добре ви можете захистити маркер доступу, дотримуючись двох варіантів.

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