Android:在共享首选项中存储身份验证令牌是一个好主意吗?

时间:2013-10-29 21:30:37

标签: android web-services authentication sharedpreferences token

我有一个与服务器通信的应用程序。 当用户登录到应用程序时,服务器上会创建一个身份验证令牌,并将其存储在应用程序的SharedPreferences中,每当应用程序从Web服务请求数据时,都会验证身份验证令牌。

我的问题是,将身份验证令牌存储在SharedPreferences中是否安全?我问,因为具有root权限的用户可以访问首选项,提取令牌并使用它。

在这方面是否有更多的安全措施?

3 个答案:

答案 0 :(得分:36)

简而言之,是的,这是一件非常合理的事情。

除此之外,您可以做的最好的事情就是混淆。如果将令牌保留在内存中,则root用户可以查看该令牌。如果你加密它,你也必须将加密密钥存储在设备上,否则你将无法使用令牌......并且密钥可以像令牌一样容易被盗。

如果有人在设备上拥有root权限,则所有投注均已关闭。不要针对那种情况进行优化。如果您的应用程序具有超级高安全性,请不要让它在root设备上运行,或实现远程擦除功能,用户可以报告其设备被盗,并且您可以使服务器上的令牌无效。

Android 4.3引入了Android Keystore。据称这为加密密钥提供了一个安全的存储。这可用于存储用于解密使用传统方法存储的加密令牌的密钥。但是,引用的链接没有提到root设备如何影响其安全性。

更新2018年:大多数现代Android设备都通过SoC提供的可信执行环境(TEE)hardware-backed keystores。这使得黑客无法获得密钥库主密钥,否则密钥库主密钥将被解密您存储在Android密钥库中的密钥。

嗯,“不可能”是一个强有力的词。最好说“不可行”。意思是,您需要像电子显微镜这样的东西来扫描融合到提供TEE的SoC中的位。如果你是那种数据需要这种关注的人,你可能会遇到更大的问题。

答案 1 :(得分:1)

现在有一种更简单快捷的方法来加密数据,因为有一个 SharedPreferences 的实现来加密密钥和值。您可以在 Android JetPack Security 中使用 EncryptedSharedPreferences。

只需将 AndroidX Security 添加到您的 build.gradle 中:

implementation 'androidx.security:security-crypto:1.0.0-rc01'

你可以这样使用它:

String masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC);

SharedPreferences sharedPreferences = EncryptedSharedPreferences.create(
    "secret_shared_prefs",
    masterKeyAlias,
    context,
    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);

// use the shared preferences and editor as you normally would
SharedPreferences.Editor editor = sharedPreferences.edit();

查看更多详情:https://android-developers.googleblog.com/2020/02/data-encryption-on-android-with-jetpack.html

官方文档:https://developer.android.com/reference/androidx/security/crypto/EncryptedSharedPreferences

答案 2 :(得分:0)

如果担心可以从SharedPreferences读取令牌,一个好的经验法则是为存储的数据提供一定程度的加密。

此响应概述了一个加密数据的简单类: What is the most appropriate way to store user settings in Android application