我应该在内存或sqlite中安全地保存令牌吗?或者请建议

时间:2017-03-21 09:24:47

标签: android

几天前我开始学习Android,到目前为止,我完成了实现Login Activity,Main Activity,它扩展了抽象的Base活动。

单击

导航栏项目从碎片打开xml。

我对成功登录后收到的令牌有疑问。成功登录后,此令牌将与每个请求一起使用以获取数据。我应该安全地将令牌保存在sqlite数据库中,还是应该在Main Activity中创建一个公共属性?主要活动将始终保留在内存中,因为这将打开片段。

7 个答案:

答案 0 :(得分:4)

我可以建议3种选择: 1)您可以将令牌保存到文件中,如下所示:

public static void saveToken(Context ctx, String fileName, Object token) {
        if (token == null) {
            ctx.deleteFile(fileName);
        } else {
            ObjectOutputStream out = null;
            try {
                FileOutputStream fout = ctx.openFileOutput(fileName, 0);
                out = new ObjectOutputStream(fout);
                out.writeObject(token);
                fout.getFD().sync();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (out != null)
                        out.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

确保对象token实现java.io.Serializable interface

API级别24之前的用法:

saveToken(appContext, someFileName, someTokenObject);

使用API​​级别24及更高版本:

saveToken(appContext.createDeviceProtectedStorageContext(), someFileName, someTokenObject);

2)将SQLCipher库用于加密数据库。

3)您可以使用密钥库系统https://developer.android.com/training/articles/keystore.html

加密您的令牌

答案 1 :(得分:1)

使用SharedPreferences并确保您使用Context.MODE_PRIVATE这种方式只有您的应用才能访问数据。 SharedPreferences是持久性商店

e.g。

SharedPreferences prefs = context.getPreferences(Context.MODE_PRIVATE);
prefs.edit().putString("token", token).apply();
token = prefs.getString("token");

为什么不使用SQLite:

SQLite是一个数据库,以表格数据为目标,单个令牌不适合这种用例。

为什么不存储在主要活动中:

主要活动在应用程序安装的生命周期内不会出现,可以随时由操作系统清理。它不是持久性数据存储。

答案 2 :(得分:0)

  

我应该安全地将令牌保存在sqlite数据库中,还是应该在Main Activity中创建一个公共属性?主要活动将始终保留在内存中,因为这将打开片段。

Official Android documentation已经在“安全和隐私的最佳做法”一节中回答了您的问题。它给出了以下声明:

  

如果您可以访问用户数据并且可以避免存储或传输它,请不要存储或传输数据

换句话说,如果你可以避免持久化,那么不会坚持

你在问题​​中提到了“公共财产”,这让我想知道能见度修饰语的概念是否还不清楚。 Java publicprivate修饰符适用于controlling access to the members of your class。根据{{​​3}},它们与安全性无关。

如果您将令牌保留在内存中,作为public字段或其他字段,您可能会通过将令牌存储在char[]而不是String。这也在this answer here详细说明。

最后,如果您必须存储令牌,则sqlite数据库不是正确的位置。相反,您应该使用提供的this canonical answer,这将在设备受到损害的情况下更难以提取令牌。上面文档的链接包含代码示例。如果这被证明太难使用,那么它周围会有一些包装,包括KeyStore

答案 3 :(得分:0)

1)将令牌值存储在基本应用程序单例中(您的应用程序必须是BaseApplication的实例)

public class BaseApplication extends Application {
    // token
    private String token = null;
    public String getToken() {return this.token;}
    public void setToken(String token) {this.token = token;}
}

通过上面的实现,您将能够从任何活动/片段设置并获取标记值。但是,该值不是持久的,一旦应用程序结束,它将丢失。

备注:如果您使用令牌进行REST api访问,则可以使用与上述类似的解决方案将令牌存储在后台服务实例中。

2)使用SharedPreferences - 如果您想在应用程序的运行之间存储令牌的值,这是推荐的方法。

请参阅@Ryan的回答。

答案 4 :(得分:0)

您可以使用SharedPreferences存储token.it可通过应用程序使用。

答案 5 :(得分:-1)

最好使用SqliteRealm。并存储在应用程序内存中而不是外部存储器中。至于驻留在应用程序内存中的数据,我们不必担心安全问题。保存在MainActivity中不是一个好的解决方案,因为一旦应用程序关闭,这将被清除。

存储在Shared Preference也是一种选择。但是如果用户从设置中清除缓存,则该值也将被清除。 Realm Android Reference Link

答案 6 :(得分:-1)

您可以将其存储在共享首选项中,因为这是令牌。

现在进入安全部分您显然可以对共享首选项使用加密。

例如,您可以在图书馆下方使用很多未清项目 https://github.com/ophio/secure-preferences 关于要加密的java文件中的密钥,您需要确保在将proguard上传到playstore之前应用它。

现在,通过共享首选项,您的令牌完全安全。

为了将其保存在sqlite中而不是通过解码或root访问,您的db文件也可以作为首选项访问。关于设置中的清晰数据,我认为它也会删除你的sqlite数据。虽然不确定。

我希望它会帮助你。