Как безопасно сохранить токен доступа Oauth в 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();

person George Thomas    schedule 26.04.2017    source источник
comment
Я использую эту библиотеку для защиты токена доступа: github.com/yakivmospan/scytale. Я также читаю это artikel перед использованием этой библиотеки, чтобы понять, как работает AndroidKeyStore: proandroiddev.com/   -  person Erlang Parasu    schedule 29.06.2020


Ответы (2)


Вам не нужно сохранять токен доступа, так как он все равно недолговечен. Достаточно сохранить его в памяти.

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

  • In a file
    • Either directly in a file in the internal storage
    • или используя SharedPreferences
    • или в базе данных
  • Использование AccountManager

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

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

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.

person rds    schedule 12.05.2017

Мы используем собственный экземпляр 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, я бы, вероятно, использовал это. Если нет, это немного тяжело для простого сохранения токена.

РЕДАКТИРОВАТЬ:

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

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

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

person Jamie Dulaney    schedule 15.05.2017