2012-04-15 22 views
80

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 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 descompilar 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?¿Cómo almacenar de forma segura el token de acceso y el secreto en Android?

+1

¿Cómo almaceno la clave y el secreto del consumidor (no es seguro protegerlos)? Necesito que soliciten acceso y secreto ... ¿Cómo lo hacen las otras aplicaciones existentes que usan oauth? hmm finalmente con oauth, necesitas ocuparte de muchos más problemas de seguridad para mí ... necesito guardar el token/secreto del consumidor de forma segura y también el acceso y el secreto ... finalmente, ¿no sería más sencillo solo almacena el nombre de usuario/contraseña del usuario encriptado? ... al final, ¿no es este último mejor? Todavía no puedo ver cómo oauth es mejor ... – yeahman

+0

¿Puedes decirme ... qué archivo almacena el token de acceso? Soy nuevo en Android y traté de ejecutar la aplicación Plus de ejemplo. Pero no encuentro esto en ninguna parte [método GoogleAuthUtil.getToken().] –

Respuesta

87

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 algunas ventajas de almacenar fichas en lugar del nombre de usuario real:

    aplicaciones
  • de terceros no necesitan saber la contraseña y el usuario puede estar seguro de que sólo se envían a la original sitio (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 duración y caducan después de un cierto tiempo
  • Tokens pueden ser revocados si sospecha que se han visto comprometidos
+1

thx para la respuesta!pero ¿cómo puedo saber si mi clave de consumidor se ha visto comprometida? jaja, será difícil de decir ... ok sobre el almacenamiento del token de acceso y el secreto, ok, los guardo en las preferencias compartidas y encriptarlos, pero ¿qué pasa con la clave del consumidor y el secreto? No puedo almacenarlos en preferencias compartidas (necesitaría escribir explícitamente la clave del consumidor y el secreto en el código para guardarlo en preferencia compartida). No sé si entiendes lo que quiero decir. – yeahman

+2

Tienes que poner la aplicación de una manera (un tanto) ofuscada, para que no sean inmediatamente visibles después de la descompilación, o usar tu propia aplicación de proxy de autenticación de autentificación que tenga la clave y el secreto. Ponerlos en la aplicación es obviamente más fácil, y si piensas que el riesgo de que alguien intente descifrar tu aplicación es suficientemente bajo, toma ese enfoque. Por cierto, los puntos anteriores son para la contraseña del usuario. Si descubres que tu clave/secreto de consumidor se ha visto comprometido, puedes revocarlos también (eso, por supuesto, romperá tu aplicación). –

+0

ok thx ... iré con la ofuscación (¿me pueden recomendar alguna buena herramienta para hacerlo?) ... tener una aplicación de proxy no es muy atractiva ya que tendría que obligar a mis usuarios a registrarse en mi sitio ... no muy fácil de usar, agregando un paso adicional en toda la cadena ... – yeahman

10

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

enter image description here

Aquí es la definición oficial:

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

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

Sin embargo, al final AccountManager sólo 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 cifrado como AESCrypt o AESCrypto

Otra opción es usar Conceal library. 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); 

Hope that's helps.

+2

Buen consejo que ocultan. Parece muy fácil de usar. Y para muchos casos de uso. – lagos

1

Bueno, puede asegurar el token de acceso al seguir dos opciones.

  1. Use su token de acceso en el almacén de claves de Android que no sea inverso.
  2. función
  3. Uso NDK con un poco de cálculo que guardar su ficha y NDK con C++ código que es muy difícil de revertir
3
  1. Desde el panel Proyecto de Android Studio, seleccione "Archivos de proyecto" y crear un nuevo archivo llamado "keystore.properties" en el directorio raíz de su proyecto.

enter image description here

    archivo "keystore.properties"
  1. Abrir y guardar su token de acceso y secreto en el archivo.

enter image description here

  1. Ahora carga la lea el token de acceso y secreto en su aplicación build.gradle archivo del módulo de. Luego debe definir la variable BuildConfig para su token de acceso y secreto para que pueda acceder directamente a ellos desde su código. Su build.gradle puede parecerse a lo siguiente:

    ... ... ... 
    
    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 utilizar su token de acceso y el secreto de su código como este:

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

De esta manera no es necesario almacene el token de acceso y el secreto en texto plano dentro de su proyecto. Por lo tanto, incluso si alguien descompila su APK, nunca recibirá su token de acceso y secreto mientras los está cargando desde un archivo externo.

+0

Parece que no hay diferencia que la creación de un archivo de propiedades en lugar de la codificación difícil. – Dzshean

+0

Una buena alternativa. –

1

SharedPreferences is not una ubicación segura. En un dispositivo rooteado, easily puede leer y modificar 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 encriptar nuestros tokens con el fin de almacenarlos en, p. Ej. Preferencias compartidas. Las claves no se almacenan dentro del proceso de una aplicación, por lo que se comprometen al are harder.

Cuestiones relacionadas