我应该使用什么设备唯一ID作为加密某些值的密钥

时间:2017-03-06 12:17:54

标签: android sqlite encryption sharedpreferences

我在这里读过很多问题,但没有一个真正回答我的问题。

我知道存储密钥的最佳位置是服务器端,但我的应用程序没有服务器。此外,每次用户启动应用程序时都要求输入密码也不是一种选择。

根据我的阅读,实际存储数据有两个地方:

  • SharedPreference但加密它:这意味着拥有root用户可以轻松访问xml文件,如果反编译apk可以获得实际值
  • sqlite database中,但实际上只是使用sqlite数据库浏览器来读取数据。

基本上我想存储两件事:

  • 可以通过登录Web浏览器随时重置的令牌
  • 用户购买的应用内购买。

对于应用内购买,我可以解决这个问题非常简单:在每个应用上查询启动购买的商品。这意味着即使应用程序在SharedPreferences中存储值,对于查询失败的情况,如果不是这样的话,我仍会覆盖此值。

有一件事是决定的:不要将它们以纯文本形式存储,而是将其包含在内。 至于加密,我想为每个应用程序安装使用某种唯一ID作为AES的关键。因为这是事情,例如,如果我在所有设备上使用相同的硬编码密钥加密应用内购买值,则可以在已植根的设备上复制购买设备的SharedPreference值,并无需付费即可访问应用。我想避免这种情况,并且通过使用可能Settings.Secure.ANDROID_ID,我可以简单地加密在任何其他设备上不一样的东西,更重要的是,即使开发人员也无法访问解密。我可以使用哪种密钥取决于设备,并允许对该设备进行加密。这意味着将备份复制到另一台设备是行不通的,因为解密会返回不同的结果。

我知道这方面有很多问题,可能我的问题会被低估,但是自那些问题以来,许多Android版本都有所改变。

基础知识仍然存在:我如何最安全地存储与我的Android应用程序相关的一些值?

2 个答案:

答案 0 :(得分:0)

将Imei用于唯一设备ID

来自

public static String getDeviceIMEI(Context context) {

    TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

    if (telephonyManager.getDeviceId() != null)
        return telephonyManager.getDeviceId();

    return "";
}

答案 1 :(得分:0)

Settings.Secure #ANDROID_ID将Android ID作为unique for each user 64位十六进制字符串返回。

import android.provider.Settings.Secure;

private String android_id = Secure.getString(getContext().getContentResolver(),
                                                        Secure.ANDROID_ID);