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

Android:在共享首选项中存储身份验证令牌是个好主意吗?,android,web-services,authentication,sharedpreferences,token,Android,Web Services,Authentication,Sharedpreferences,Token,我有一个与服务器通信的应用程序。 当用户登录到应用程序时,身份验证令牌被包装在服务器上并存储在应用程序的SharedReferences中,并且每当应用程序从web服务请求数据时,身份验证令牌都会被验证 我的问题是,将身份验证令牌存储在SharedReferences中是否安全?我这样问是因为具有root权限的用户可以访问首选项、提取令牌并使用它 总之,是的,这样做是完全合理的 除此之外,你能做的最好的事情就是模糊处理。如果您将令牌保存在内存中,则root用户可以窥视该令牌。如果您对其进行加密,

我有一个与服务器通信的应用程序。 当用户登录到应用程序时,身份验证令牌被包装在服务器上并存储在应用程序的
SharedReferences
中,并且每当应用程序从web服务请求数据时,身份验证令牌都会被验证

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


总之,是的,这样做是完全合理的

除此之外,你能做的最好的事情就是模糊处理。如果您将令牌保存在内存中,则root用户可以窥视该令牌。如果您对其进行加密,您还必须将加密密钥存储在设备上,否则您将无法使用令牌……而且密钥可能会像令牌一样容易被盗

如果有人在设备上拥有root用户,则所有赌注都将无效。不要针对这种情况进行优化。如果您的应用程序是超级复制程序高安全性,请不要允许它在根设备上运行,或实施远程擦除功能,用户可以报告其设备被盗,您可以在服务器上使令牌无效

安卓4.3引入了。据说它为加密密钥提供了一个安全的存储。这可以用来存储用于解密用传统方法存储的加密令牌的密钥。但是,引用的链接没有提到根设备如何影响此设备的安全性

2018年更新:大多数现代安卓设备都通过SoC提供的可信执行环境(TEE)实现了。这使得黑客不可能(见下文)获得密钥库主密钥,否则需要该密钥来解密存储在Android密钥库中的密钥


“不可能”是一个强有力的词。最好说它“不可行”。也就是说,你需要像电子显微镜一样的东西来扫描融合到SoC中的位元,从而提供T形三通。如果您的数据值得关注,那么您可能会遇到更大的问题。

如果您担心令牌可能会从SharedReference中读取,那么一个好的经验法则是为存储的数据提供一定程度的混淆

此响应概述了一个用于混淆SharedReferences数据的简单类:

现在有一种更简单、更快速的数据加密方法,因为有一种对密钥和值进行加密的SharedReference实现。您可以在Android JetPack安全中使用EncryptedSharedReferences

只需将AndroidX安全性添加到您的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();
请参阅更多详细信息:


官方文件:

这不是加密,而是混淆。如果密钥存储在设备上,您只是在为敏感数据添加一个间接级别。Android密钥库似乎也不是根设备的解决方案@DavidSantiagoTuriño如果设备是根设备,恶意代理可以直接从内存访问解密的数据。当设备根目录时,所有的赌注都被取消了。当然,我知道。这只是为了说明该密钥库发生了什么,尽管链接没有说明任何内容:)