MASTG-KNOW-0036: Preferências Compartilhadas
A API SharedPreferences é comumente usada para salvar permanentemente pequenas coleções de pares chave-valor.
Desde o Android 4.2 (API nível 17), o objeto SharedPreferences só pode ser declarado como privado (e não legível globalmente, ou seja, acessível a todos os aplicativos). No entanto, como os dados armazenados em um objeto SharedPreferences são gravados em um arquivo XML em texto simples, seu uso indevido pode frequentemente levar à exposição de dados sensíveis.
Considere o seguinte exemplo:
var sharedPref = getSharedPreferences("key", Context.MODE_PRIVATE)
var editor = sharedPref.edit()
editor.putString("username", "administrator")
editor.putString("password", "supersecret")
editor.commit()
Uma vez que a atividade é chamada, o arquivo key.xml será criado com os dados fornecidos. Este código viola várias práticas recomendadas.
- O nome de usuário e a senha são armazenados em texto claro em
/data/data/<nome-do-pacote>/shared_prefs/key.xml.
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="username">administrator</string>
<string name="password">supersecret</string>
</map>
MODE_PRIVATE torna o arquivo acessível apenas pelo aplicativo que o chamou. Veja "Usar SharedPreferences no modo privado".
Existem outros modos inseguros, como
MODE_WORLD_READABLEeMODE_WORLD_WRITEABLE, mas eles foram descontinuados desde o Android 4.2 (API nível 17) e removidos no Android 7.0 (API nível 24). Portanto, apenas aplicativos em execução em uma versão mais antiga do sistema operacional (android:minSdkVersionmenor que 17) serão afetados. Caso contrário, o Android lançará uma SecurityException. Se um aplicativo precisar compartilhar arquivos privados com outros aplicativos, é melhor usar um FileProvider com FLAG_GRANT_READ_URI_PERMISSION. Veja Compartilhamento de Arquivos para mais detalhes.
Você também pode usar EncryptedSharedPreferences, que é um wrapper de SharedPreferences que criptografa automaticamente todos os dados armazenados nas preferências compartilhadas.
Aviso
A biblioteca de criptografia de segurança do Jetpack, incluindo as classes EncryptedFile e EncryptedSharedPreferences, foi descontinuada. No entanto, como um substituto oficial ainda não foi lançado, recomendamos usar essas classes até que esteja disponível.
var masterKey: MasterKey? = null
masterKey = Builder(this)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()
val sharedPreferences: SharedPreferences = EncryptedSharedPreferences.create(
this,
"secret_shared_prefs",
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
val editor = sharedPreferences.edit()
editor.putString("username", "administrator")
editor.putString("password", "supersecret")
editor.commit()