Вопрос по android – Как безопасно хранить токен доступа и секрет в Android?

101

Я собираюсь использовать oAuth для получения почты и контактов из Google. Я не хочу просить пользователя каждый раз входить в систему для получения токена доступа и секрета. Из того, что я понял, мне нужно хранить их с моим приложением либо в базе данных, либоSharedPreferences, Но меня это немного беспокоит вопросы безопасности. Я читал, что вы можете зашифровать и расшифровать токены, но злоумышленнику легко декомпилировать ваш apk и классы и получить ключ шифрования.
What's the best method to securely store these tokens in Android?

Как я могу хранить ключ и секретный ключ пользователя (их жесткая защита не защищена)? мне нужно, чтобы они запросили маркер доступа и секрет .. как другие существующие приложения, использующие oauth, делают это? хм, наконец, с oauth, вам нужно позаботиться о гораздо большем количестве проблем безопасности для меня .... мне нужно надежно хранить токен / секретный ключ пользователя, а также токен доступа и секрет ... наконец, было бы проще просто храните имя пользователя / пароль в зашифрованном виде ... ... в конце концов, не лучше ли последнее? Я просто до сих пор не вижу, как лучше oauth ... yeahman
ты можешь сказать мне ... в каком файле хранится токен доступа ?? Я новичок в Android, и я попытался запустить образец приложения Plus. Но я не могу найти это нигде [метод GoogleAuthUtil.getToken ().] Abhishek Kaushik

Ваш Ответ

5   ответов
14

Менеджер по работе с клиентам. По мнению этих ребят, это считается наилучшей практикой.

Вот официальное определение:

Этот класс обеспечивает доступ к централизованному реестру сетевых учетных записей пользователя. Пользователь вводит учетные данные (имя пользователя и пароль) один раз для каждой учетной записи, предоставляя приложениям доступ к онлайн-ресурсам с одобрением в один клик.

Подробное руководство по использованию AccountManager:

Уди Коэн учебникPilanites блог Google IO презентация

Однако в конце AccountManager сохраняет ваш токен только в виде простого текста. Итак, я бы посоветовал зашифровать ваш секрет, прежде чем хранить его в AccountManager. Вы можете использовать различные библиотеки шифрования, такие как AESCrypt или AESCrypto

Другой вариант - использовать Скрытая библиотека. Это достаточно безопасно для Facebook и намного проще в использовании, чем AccountManager. Вот фрагмент кода для сохранения секретного файла с помощью Conceal.

byte[] cipherText = crypto.encrypt(plainText);
byte[] plainText = crypto.decrypt(cipherText);
Хороший совет, что скрывать. Выглядит очень просто в использовании. И для многих случаев использования. lagos
6
В панели проектов Android Studio выберите «Файлы проекта» и создайте новый файл с именем «keystore.properties» в корневом каталоге вашего проекта.

Откройте файл "keystore.properties" и сохраните свой токен доступа и секретный файл в этом файле.

Теперь загрузите прочитанный токен доступа и секрет в свойприложени модуль Build.gradle файл. Затем вам нужно определить переменную BuildConfig для вашего токена доступа и секрета, чтобы вы могли напрямую получить к ним доступ из своего кода. Ваш 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"]
    }
}

Вы можете использовать свой токен доступа и секрет в своем коде следующим образом:

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

Таким образом, вам не нужно хранить токен доступа и секрет в виде простого текста внутри вашего проекта. Поэтому, даже если кто-то декомпилирует ваш APK, он никогда не получит ваш токен доступа и секрет, когда вы загружаете их из внешнего файла.

Хороший альтернативный способ. M.Noman
Похоже, нет никакой разницы, что создание файла свойств вместо жесткого кодирования. Dzshean
Это очень хороший способ хранения некоторых токенов, таких как токены доступа API. если вы хотите сохранить учетные данные пользователя, лучше использовать NDK. TheTeslaa
Я хочу написать токен во время выполнения, возможно, мой токен каждый раз меняется при открытии приложения. Rehan Sarwar
Это то же самое, что жесткое кодирование ... Toufic Batache
103

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

Существует несколько преимуществ хранения токенов вместо действительного имени пользователя:

Сторонним приложениям не нужно знать пароль, и пользователь может быть уверен, что они отправят его только на оригинальный сайт (Facebook, Twitter, Gmail и т. Д.) Даже если кто-то украдет токен, он не увидит пароль (который пользователь может использовать и на других сайтах) Обычно токены имеют срок действия и истекают через определенное время Токены могут быть отозваны, если вы подозреваете, что они были скомпрометированы
Если данные приложения очищены, то токен обновления теряется, что, вероятно, не то, что хотел пользователь. rds
Вы должны либо поместить в приложение (несколько) запутанный способ, чтобы они не были сразу видны после декомпиляции, либо использовать свое собственное веб-приложение для прокси-сервера авторизации, которое имеет ключ и секрет. Поместить их в приложение, очевидно, проще, и если вы считаете, что риск того, что кто-то попытается взломать ваше приложение, достаточно низок, воспользуйтесь этим подходом. Кстати, пункты выше предназначены для пароля пользователя. Если вы обнаружите, что ваш ключ / секрет потребителя был скомпрометирован, вы также можете отозвать их (хотя это, конечно, сломает ваше приложение). Nikolay Elenkov
спасибо за ответ! но как я могу узнать, что мой потребительский ключ был скомпрометирован? лол, это будет трудно сказать .. хорошо о хранении токена доступа и секрета, хорошо, я сохраняю их в общих настройках и шифрую их, но как насчет ключа и секрета потребителя? Я не могу хранить их в sharedpreferences (мне нужно было бы явно написать ключ и секретный ключ в коде, чтобы сохранить его в sharedpreference в первую очередь) .. не знаю, понимаете ли вы, что я имею в виду. yeahman
@ NikolayElenkov: Вы писали: «Что касается шифрования, вы должны либо потребовать, чтобы пользователь вводил расшифрованную парольную фразу каждый раз (таким образом, отказавшись от цели кэширования учетных данных), либо сохранить ключ в файл, и вы получите ту же проблему. ». Что, если взломщики обратят ваше приложение, чтобы понять, как работает шифрование? Ваша защита может быть нарушена. Лучше ли хранить такую информацию (токен, шифрование ...) с использованием собственного кода? anhldbk
ok thx .. я пойду путём запутывания (можете ли вы порекомендовать какой-нибудь хороший инструмент для этого?) ... наличие прокси-веб-приложения не очень привлекательно, так как мне пришлось бы заставлять своих пользователей регистрироваться на моем сайте .. не очень удобное добавление дополнительного шага во всей цепочке ... yeahman
4

не являетс безопасное место само по себе. На рутированном устройстве мы легко можем читать и изменять все приложения SharedPrefereces xml. Так что токены должны истекать относительно часто. Но даже если токен истекает каждый час, новые токены все равно можно украсть из . Android KeyStore следует использовать для длительного хранения и извлечения криптографических ключей, которые будут использоваться для шифрования наших токенов с целью их хранения, например, в. или база данных. Ключи не хранятся в процессе приложения, поэтому они сложнее быть скомпрометированным.

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

Тогда где мы можем их хранить? Milind Mevada
2

Используйте токен доступа в хранилище ключей Android, который не будет обратным. Используйте функцию NDK с некоторыми вычислениями, которые сохраняют ваш токен, и NDK с кодом C ++, который очень трудно перевернут

Похожие вопросы