¿Cómo almacenar de forma segura el token de acceso y el secreto en Android?

Voy a usar oAuth para buscar correos y contactos de google. No deseo pedirle al usuario cada vez que inicie sesión para obtener un token de acceso y un secreto. Por lo que entendí, necesito almacenarlos con mi aplicación en una base de datos o en SharedPreferences . Pero estoy un poco preocupado por los aspectos de seguridad con eso. Leí que puede encriptar y descifrar los tokens, pero es fácil para un atacante simplemente descomstackr su apk y clases y obtener la clave de cifrado.
¿Cuál es el mejor método para almacenar de forma segura estos tokens en Android?

Guárdelos como preferencias compartidas. Esos son privados por defecto, y otras aplicaciones no pueden acceder a ellos. En dispositivos rooteados, si el usuario permite explícitamente el acceso a alguna aplicación que intenta leerlos, es posible que la aplicación pueda usarlos, pero no puede protegerse contra eso. En cuanto al cifrado, debe exigir al usuario que ingrese la frase clave de descifrado cada vez (anulando así el propósito de las credenciales de almacenamiento en caché), o guardar la clave en un archivo, y se obtiene el mismo problema.

Hay algunos beneficios de almacenar tokens en lugar de la contraseña de usuario real:

  • Las aplicaciones de terceros no necesitan saber la contraseña y el usuario puede estar seguro de que solo la envía al sitio original (Facebook, Twitter, Gmail, etc.)
  • Incluso si alguien roba un token, no puede ver la contraseña (que el usuario podría estar usando en otros sitios también)
  • Los tokens generalmente tienen una vida útil y caducan después de un cierto tiempo
  • Los tokens pueden ser revocados si sospecha que se han visto comprometidos

Puede almacenarlos en AccountManager . Se considera la mejor práctica según estos tipos.

enter image description here

Aquí está la definición oficial:

Esta clase proporciona acceso a un registro centralizado de las cuentas en línea del usuario. El usuario ingresa las credenciales (nombre de usuario y contraseña) una vez por cuenta, lo que otorga a las aplicaciones acceso a los recursos en línea con la aprobación de “un clic”.

Para obtener una guía detallada sobre cómo usar AccountManager:

  • Tutorial de Udi Cohen
  • Blog de Pilanites
  • Presentación de Google IO

Sin embargo, al final, AccountManager solo almacena el token como texto sin formato. Por lo tanto, sugeriría encriptar su secreto antes de almacenarlos en AccountManager. Puede utilizar varias bibliotecas de encriptación como AESCrypt o AESCrypto.

Otra opción es usar la biblioteca Oculta . Es lo suficientemente seguro para Facebook y mucho más fácil de usar que AccountManager. Aquí hay un fragmento de código para guardar un archivo secreto usando Ocultar.

 byte[] cipherText = crypto.encrypt(plainText); byte[] plainText = crypto.decrypt(cipherText); 
  1. Desde el panel Proyecto de Android Studio, seleccione “Archivos de proyecto” y cree un nuevo archivo llamado “keystore.properties” en el directorio raíz de su proyecto.

enter image description here

  1. Abra el archivo “keystore.properties” y guarde su token de acceso y secreto en el archivo.

enter image description here

  1. Ahora cargue la lectura del token de acceso y el secreto en el archivo build.gradle de su módulo de aplicación . Luego debe definir la variable BuildConfig para su token de acceso y secreto para que pueda acceder directamente a ellos desde su código. Tu build.gradle puede verse como sigue:

     ... ... ... 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"] } } 
  2. Puede usar su Token de acceso y secreto en su código de esta manera:

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

De esta forma, no necesita almacenar el token de acceso y el secreto en texto plano dentro de su proyecto. Por lo tanto, incluso si alguien descomstack su APK, nunca recibirá su token de acceso y secreto mientras los está cargando desde un archivo externo.

SharedPreferences no es una ubicación segura. En un dispositivo rooteado, podemos leer y modificar fácilmente todas las aplicaciones ‘SharedPrefereces xml’s’. Incluso si un token caduca cada hora, aún pueden robar tokens más nuevos de SharedPreferences. Android KeyStore se debe utilizar para el almacenamiento a largo plazo y la recuperación de claves criptográficas que se utilizarán para cifrar nuestros tokens con el fin de almacenarlos, por ejemplo, SharedPreferences. Las claves no se almacenan dentro del proceso de una aplicación, por lo que son más difíciles de comprometer.

Bueno, puedes asegurar tu token de acceso siguiendo dos opciones.

  1. Utilice guardar su token de acceso en el almacén de claves de Android que no estaría en reversa.
  2. Use la función NDK con algunos cálculos que guardan su token y NDK con código de C ++ que es muy difícil de invertir