Come archiviare in modo sicuro il token di accesso e il segreto in Android?


123

Userò oAuth per recuperare messaggi e contatti da Google. Non voglio chiedere ogni volta all'utente di accedere per ottenere un token di accesso e un segreto. Da quello che ho capito, ho bisogno di memorizzarli con la mia applicazione in un database o SharedPreferences. Ma sono un po 'preoccupato per gli aspetti di sicurezza con quello. Ho letto che puoi crittografare e decrittografare i token, ma è facile per un utente malintenzionato decompilare l'apk e le classi e ottenere la chiave di crittografia.
Qual è il metodo migliore per archiviare in modo sicuro questi token su Android?


1
Come si memorizzano la chiave utente e il segreto (l'hardconding non è protetto)? ne ho bisogno per richiedere il token di accesso e il segreto .. come fanno le altre app esistenti che utilizzano oauth? hmm finalmente con oauth, devi occuparti di molti più problemi di sicurezza per me ... ho bisogno di mantenere il token / segreto del consumatore in modo sicuro e anche il token di accesso e il segreto ... finalmente non sarebbe più semplice da memorizzare semplicemente il nome utente / password dell'utente crittografati? ... alla fine, non è meglio quest'ultima? Non riesco ancora a vedere come oauth sia meglio ...
yeahman

potete dirmi ... quale file memorizza il token di accesso ?? Sono nuovo su Android e ho provato a eseguire l'app Plus di esempio, ma non lo trovo da nessuna parte [metodo GoogleAuthUtil.getToken ().]
Abhishek Kaushik

Risposte:


117

Memorizzali come preferenze condivise . Quelli sono per impostazione predefinita privati ​​e altre app non possono accedervi. Su un dispositivo rooted, se l'utente consente esplicitamente l'accesso a un'app che sta tentando di leggerli, l'app potrebbe essere in grado di usarli, ma non è possibile proteggersi da ciò. Per quanto riguarda la crittografia, è necessario richiedere all'utente di inserire ogni volta la passphrase di decrittografia (annullando così lo scopo della memorizzazione nella cache delle credenziali) o salvare la chiave in un file e si ottiene lo stesso problema.

Ci sono alcuni vantaggi nell'archiviare i token invece dell'effettiva password del nome utente:

  • Le app di terze parti non hanno bisogno di conoscere la password e l'utente può essere certo di inviarla solo al sito originale (Facebook, Twitter, Gmail, ecc.)
  • Anche se qualcuno ruba un token, non riesce a vedere la password (che l'utente potrebbe utilizzare anche su altri siti)
  • I token generalmente hanno una durata e scadono dopo un certo tempo
  • I token possono essere revocati se sospetti che siano stati compromessi

1
grazie per la risposta! ma come posso sapere se la mia chiave utente è stata compromessa? lol sarà difficile dirlo .. ok sulla memorizzazione del token di accesso e del segreto, ok li salvo nelle preferenze condivise e li crittografa, ma che ne dici della chiave utente e del segreto? Non posso memorizzarli in sharedpreferences (avrei bisogno di scrivere esplicitamente la chiave del consumatore e il segreto nel codice per salvarlo in sharedpreference in primo luogo) .. non so se capisci cosa intendo.
yeahman

2
Devi inserire l'app in un modo (un po ') offuscato, in modo che non siano immediatamente visibili dopo la decompilazione, oppure utilizzare la tua webapp proxy di autenticazione che ha la chiave e il segreto. Metterli nell'app è ovviamente più facile e se pensi che il rischio che qualcuno tenti di violare la tua app sia sufficientemente basso, adotta questo approccio. BTW, i punti sopra sono per la password utente. Se scopri che la tua chiave / segreto utente è stato compromesso, puoi revocare anche quelli (ciò, ovviamente, interromperà la tua app).
Nikolay Elenkov

1
@NikolayElenkov: hai scritto "Per quanto riguarda la crittografia, devi richiedere all'utente di inserire la passphrase di decrittografia ogni volta (vanificando così lo scopo della memorizzazione nella cache delle credenziali) o salvare la chiave in un file e ottieni lo stesso problema." . E se i cracker invertissero la tua app per avere un'idea di come funziona la crittografia? La tua difesa potrebbe essere rotta. È consigliabile archiviare tali informazioni (token, crittografia ...) utilizzando codice nativo?
anhldbk

1
Se i dati dell'app vengono cancellati, il token di aggiornamento viene perso, il che probabilmente non è quello che voleva l'utente.
rds

1
Questo non è più il modo migliore per archiviare i token ora come un giorno!
Rahul Rastogi

19

Puoi memorizzarli in AccountManager . È considerata la migliore pratica secondo questi ragazzi.

inserisci qui la descrizione dell'immagine

Ecco la definizione ufficiale:

Questa classe fornisce l'accesso a un registro centralizzato degli account in linea dell'utente. L'utente immette le credenziali (nome utente e password) una volta per account, consentendo alle applicazioni di accedere alle risorse online con l'approvazione "con un clic".

Per una guida dettagliata su come utilizzare AccountManager:

Tuttavia, alla fine AccountManager memorizza il tuo token solo come testo normale. Quindi, suggerirei di crittografare il tuo segreto prima di memorizzarlo in AccountManager. Puoi utilizzare varie librerie di crittografia come AESCrypt o AESCrypto

Un'altra opzione è usare la libreria Nascondi . È abbastanza sicuro per Facebook e molto più facile da usare di AccountManager. Ecco uno snippet di codice per salvare un file segreto utilizzando Conceal.

byte[] cipherText = crypto.encrypt(plainText);
byte[] plainText = crypto.decrypt(cipherText);

2
Buon suggerimento che nasconde. Sembra molto facile da usare. E per molti casi d'uso.
lagos

Impossibile trovare Conceal tramite il collegamento. Può essere disattivato
user1114

10

SharedPreferences non è una posizione sicura in sé. Su un dispositivo rooted possiamo leggere e modificare facilmente gli XML SharedPrefereces di tutte le applicazioni. Quindi i token dovrebbero scadere relativamente frequentemente. Ma anche se un token scade ogni ora, i token più recenti possono comunque essere rubati da SharedPreferences. Android KeyStore dovrebbe essere utilizzato per l'archiviazione a lungo termine e il recupero di chiavi crittografiche che verranno utilizzate per crittografare i nostri token al fine di memorizzarli, ad esempio, in SharedPreferences o in un database. Le chiavi non vengono memorizzate all'interno del processo di un'applicazione, quindi è più difficile comprometterle.

Quindi più rilevante di un luogo è il modo in cui possono essere al sicuro, ad esempio utilizzando JWT di breve durata firmati crittograficamente, crittografandoli utilizzando Android KeyStore e inviandoli con un protocollo sicuro


9
Allora dove possiamo conservarli?
Milind Mevada

2
  1. Dal pannello Progetto di Android Studio, seleziona "File di progetto" e crea un nuovo file denominato "keystore.properties" nella directory principale del tuo progetto.

inserisci qui la descrizione dell'immagine

  1. Apri il file "keystore.properties" e salva il token di accesso e il segreto nel file.

inserisci qui la descrizione dell'immagine

  1. Ora caricare il letto il token di accesso e segreto nella vostra applicazione del modulo build.gradle file. Quindi è necessario definire la variabile BuildConfig per il token di accesso e il segreto in modo da poterli accedere direttamente dal codice. Il tuo build.gradle potrebbe essere simile al seguente:

    ... ... ... 
    
    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. Puoi usare il tuo token di accesso e segreto nel tuo codice in questo modo:

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

In questo modo non è necessario memorizzare il token di accesso e il segreto in testo normale all'interno del progetto. Quindi, anche se qualcuno decompila il tuo APK, non riceverà mai il tuo token di accesso e segreto mentre li stai caricando da un file esterno.


1
Sembra che non ci siano differenze tra la creazione di un file delle proprietà invece dell'hard coding.
Dzshean

Voglio scrivere il token in fase di esecuzione potrebbe essere il mio token ogni volta che viene modificato quando apro la mia app.
Rehan Sarwar

1
È un ottimo modo per archiviare alcuni token come i token di accesso API. se si desidera memorizzare le credenziali utente, l'NDK è un modo migliore.
Eric,

7
Questo non è assolutamente il modo in cui dovresti archiviare informazioni sensibili nella tua applicazione! Anche se il repository non contiene i dati utilizzando questo approccio (i dati vengono iniettati nel processo di compilazione), questo genera un file BuildConfig che ha il token / segreto in testo normale che tutti possono vedere dopo una semplice decompilazione.
Hrafn

-1

Bene, puoi proteggere il tuo token di accesso seguendo due opzioni.

  1. Usa salva il tuo token di accesso nel keystore di Android che non sarebbe inverso.
  2. Usa la funzione NDK con alcuni calcoli che salvano il tuo token e NDK con codice c ++ che è molto difficile da invertire
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.