Как безопасно сохранить токен доступа 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 или несколько сертификатов, которые используются для цифровой подписи приложения. Это делается для того, чтобы кто-то еще не загружал приложение, имеющее то же имя пакета, что и ваше, и заменяя его.