【问题标题】:Android: Is it a good idea to store Authentication Token in Shared Preferences?Android:将身份验证令牌存储在共享首选项中是个好主意吗?
【发布时间】:2013-11-09 06:39:24
【问题描述】:

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

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

在这方面是否有更高的安全性?

【问题讨论】:

    标签: android web-services authentication sharedpreferences token


    【解决方案1】:

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

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

    如果有人在设备上拥有 root 权限,则所有赌注都将取消。不要针对这种情况进行优化。如果您的应用具有超高安全性,请不要让它在有根设备上运行,或者实现远程擦除功能,用户可以报告他们的设备被盗,您可以使服务器上的令牌无效。

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

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

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

    【讨论】:

    • Android Keystore 似乎也不是根设备的解决方案androidauthority.com/…
    • @DavidSantiagoTuriño 如果设备已root,恶意代理可以直接从内存中访问解密数据。设备植根后,所有赌注都将取消。
    • 当然,我知道。这只是为了说明该密钥库会发生什么,尽管链接没有说明它:)
    【解决方案2】:

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

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

    【讨论】:

    • 这不是加密,而是混淆。如果密钥存储在设备上,那么您只是为敏感数据添加了一定程度的间接性。
    【解决方案3】:

    现在有一种更简单、更快捷的方式来加密数据,因为 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-13
      • 1970-01-01
      • 2021-08-30
      • 1970-01-01
      • 2011-08-11
      • 2022-10-15
      • 2011-09-13
      • 2021-06-02
      相关资源
      最近更新 更多