Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save Oauth Access token securely in android

Tags:

I have access token from the server after authentication lets say "uyhjjfjfgg567f8fhjkkf" now I want to save it in the device securely. I looked in Keystore and Keychain in android developer sites. I dont clearly understand how it works and how we should retrieve the token from the keystore.

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(); 
like image 310
George Thomas Avatar asked Apr 26 '17 08:04

George Thomas


People also ask

How secure tokens are stored in Android?

Android KeyStore should be used for long term storage and retrieval of cryptographic keys which will be used to encrypt our tokens in order to store them in e.g. SharedPreferences or a database. The keys are not stored within an application's process, so they are harder to be compromised.

How do I store access token securely?

Most guidelines, while advising against storing access tokens in the session or local storage, recommend the use of session cookies. However, we can use session cookies only with the domain that sets the cookie. Another popular suggestion is to store access tokens in the browser's memory.


2 Answers

You don't need to save the access token, since it has short life anyway. Keeping it in memory is good enough.

You do need to keep the refresh token, and you have a few options for that:

  • In a file
    • Either directly in a file in the internal storage
    • or using SharedPreferences
    • or in a Database
  • Using the AccountManager

Consider using the StoredCredential. For the flow itself, I recommend you to use Google AppAuth library.

Of course, you can also encrypt the key using a cipher:

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); } 

And the key can be stored in the KeyStore.

like image 136
rds Avatar answered Sep 19 '22 08:09

rds


We use a custom SharedPreference instance that encrypts the keys and values when adding, and decrypts when requesting.

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 

I would only recommend using SharedPreferences if the values are encrypted, because even though the xml file is only available to the app, it can be accessed on rooted devices.

If you already using a SqlLiteDB, I would probably use that. If not, it's bit heavy for just saving a token.

EDIT:

An oauth token is completely unrelated to the key and keystore used to sign the app.

The oauth token is a token provided by the server after validating the user's credentials, within the app.

The keystore contains 1 or more certificates that is used to digitally sign the app. This is to prevent someone else from uploading an app that has the same package name as yours and replacing it.

like image 22
Jamie Dulaney Avatar answered Sep 21 '22 08:09

Jamie Dulaney