Как безопасно сохранить токен доступа Oauth Access в android

У меня есть маркер доступа с сервера после того, как аутентификация позволяет сказать "uyhjjfjfgg567f8fhjkkf" теперь, когда я хочу сохранить его в устройстве надежно. Я посмотрел в Keystore и Keychain на сайтах разработчиков Android. Я не понимаю, как это работает и как мы должны извлечь токен из хранилища ключей.

KeyPairGenerator kpg = KeyPairGenerator.getInstance(
        KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
kpg.initialize(new KeyGenParameterSpec.Builder(
        alias,
        KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
        .setDigests(KeyProperties.DIGEST_SHA256,
            KeyProperties.DIGEST_SHA512)
        .build());

KeyPair kp = kpg.generateKeyPair();


/*
 * Load the Android KeyStore instance using the the
 * "AndroidKeyStore" provider to list out what entries are
 * currently stored.
 */

KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
Enumeration<String> aliases = ks.aliases();

Ответ 1

Вам не нужно сохранять токен доступа, так как он имеет короткую жизнь. Сохранение его в памяти достаточно хорошее.

Вам нужно сохранить токен обновления, и у вас есть несколько вариантов для этого:

  • В файле
    • Либо непосредственно в файле во внутреннем хранилище
    • или используя SharedPreferences
    • или в базе данных
  • Используя AccountManager

Рассмотрим использование StoredCredential. Для самого потока я рекомендую вам использовать Google AppAuth library.

Конечно, вы также можете зашифровать ключ с помощью шифрования:

private static byte[] encrypt(byte[] key, byte[] text) throws GeneralSecurityException {
    final SecretKeySpec skeySpec = new SecretKeySpec(key, KEY_ALGORITHM);
    final Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec, sInitVectorSpec);
    return cipher.doFinal(text);
}

И ключ может быть сохранен в KeyStore.

Ответ 2

Here вы можете найти действительно хорошую статью от Androidauthority относительно возможностей, доступных для Android Security.

Подробный пример реализации keystore для Android можно найти здесь.

И еще один хороший вариант - Google keyczar, который вы можете найти в репозитории git для образцов и деталей. Там вы также можете найти подробный список Известные проблемы безопасности, чтобы вы могли видеть, подходит ли вам ваша дальнейшая реализация.

Для вашей текущей проблемы я бы рекомендовал перейти на Android Keystore после примера реализации во второй ссылке выше.

Удачи!

Ответ 3

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

SecurePreferences preferences = ...
preferences.edit().putString( "key", "value" ).apply(); // key and value are encrypted automatically

String value = preferences.getString( "key", null ); // key and value are decrypted automatically

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

Если вы уже используете SqlLiteDB, я бы, вероятно, использовал это. Если нет, это немного тяжело для сохранения токена.

EDIT:

Значок oauth полностью не связан с ключом и хранилищем ключей, используемым для подписи приложения.

Значок oauth - это токен, предоставляемый сервером после проверки учетных данных пользователя в приложении.

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