Android 在设备上本地存储数据

Android 在设备上本地存储数据,android,encryption,Android,Encryption,我正在制作一个应用程序,用户可以在设备上存储数据。我在考虑使用数据库存储。但我在某个地方读到过这样的信息:可以操作本地存储在设备上的数据。那么,避免这种对数据的“攻击”的最佳方式是什么呢?我一直在考虑对数据库中的每个字段进行加密,但同样,我也必须在设备上存储一个加密密钥(?),我想这也是可以找到的?那么,有人对我的想法有其他想法/改进吗 谢谢你的帮助 那么,避免这种对数据的“攻击”的最佳方式是什么呢 不要把它放在设备上 我想针对应用程序的用户保护数据 然后不要把它放在设备上。它是用户的设备和用户

我正在制作一个应用程序,用户可以在设备上存储数据。我在考虑使用数据库存储。但我在某个地方读到过这样的信息:可以操作本地存储在设备上的数据。那么,避免这种对数据的“攻击”的最佳方式是什么呢?我一直在考虑对数据库中的每个字段进行加密,但同样,我也必须在设备上存储一个加密密钥(?),我想这也是可以找到的?那么,有人对我的想法有其他想法/改进吗

谢谢你的帮助

那么,避免这种对数据的“攻击”的最佳方式是什么呢

不要把它放在设备上

我想针对应用程序的用户保护数据

然后不要把它放在设备上。它是用户的设备和用户的带宽,因此它是用户的数据

但我正在寻找一种方法,如果用户发现他/她将尝试这样做,那么这将是一个巨大的挑战

只需在内部存储器上使用数据库或其他东西,99%的安卓设备用户将无法访问您的数据。你无法阻止剩下的1%

我正在寻找一种方法,使它成为一个巨大的挑战

接受挑战:)

您应该做的第一件事是将数据存储在应用程序目录中,因为用户/常规设备上的其他应用程序无法读取数据。可从
上下文中获取应用程序数据的链接,例如。从
Environment
获取的目录是公共的

这会阻止普通用户获取数据。但是很多人都有根设备,可以毫无问题地访问数据,所以这仍然是相当不安全的

为了让它更难,你需要加密。任何没有像WEP那样从根本上被破坏的强加密都可以。使用加密可以强制用户查找密钥(和加密方法),因为加密数据无法在合理的时间内解密

这就导致了一个问题:你的应用程序在某个地方有一个可用的密钥,但用户却没有。这是你需要发挥创造力的部分,因为没有安全的方法来做到这一点

最简单的方法是在应用程序代码中以明文形式输入密钥。类似于
私有静态最终字符串SECRET=“42”
。通过简单地拥有加密文件,您将阻止大多数用户进一步挖掘,因为此时您需要一些编程技能来读取数据

如果用户具备这些技能,他可能会开始查看应用程序的代码(使用例如+)。如果你想知道对你的应用进行反向工程有多难,你也应该这样做

如果使用proguard混淆代码,则理解代码/查找加密方法+密码将变得更加困难,因为应用程序内部类、方法和变量名称将缩短为
A.B.c(d)
,类似于代码。但是对Android API的方法调用不能重命名,因为您需要重命名设备上的方法。另外,像
“42”
这样的字符串常量也不会更改

下一步是用代码动态生成的内容替换该常量。例如,下面的基本示例通过将数字除以2来构建密码。使用这种方法的优点是密码不再以明文形式存储,您需要了解/反向工程将数据转换为密码的方法

private static final byte[] password = {8, 4};
private String getPassword(byte[] data) {
    StringBuilder sb = new StringBuilder();
    for (byte b : data) {
        sb.append(String.valueof(b / 2));
    }
    return sb.toString();
}
// returns "42" if I did not make a mistake
下一个易受攻击的点是,可以很容易地找到对设备加密API的调用(因为它们无法重命名),这使得查找加密的位置变得更加容易。如果您不想编写自己的加密方法,我强烈建议您不要编写,因为这里的一个小错误可能会损坏数据或破坏完整的加密

例如,如果使用反射(通过提供
字符串中提供的方法/类的名称来调用方法),则该问题可能会变得更为严重。那个
字符串
也可以像上面的例子一样对密码进行模糊处理

private static final byte[] password = {8, 4};
private String getPassword(byte[] data) {
    StringBuilder sb = new StringBuilder();
    for (byte b : data) {
        sb.append(String.valueof(b / 2));
    }
    return sb.toString();
}
// returns "42" if I did not make a mistake
如果你做了所有这些,并且没有使用一种不像这个方法那么简单的方法,你会让它变得非常困难。例如,它可以为你做到这一点,但它不是免费的,并且有一个问题,即许多应用程序都使用相同的方法,并且比你的自定义方法有更多的人会尝试打破这一点

在你的应用程序中找到一种隐藏用于生成密钥的信息的好方法,以及一种隐藏密钥生成和加密/解密的方法,最好由你自己来解决,这样该方法本身就不是公共知识

您可以结合使用许多技术来隐藏信息,比如将其中的一部分移动到本机代码中,这样像我这样的Java人员就很难使用了,或者使用网络连接来让您的服务器做一些工作


但归根结底,所有额外的安全措施都不会让用户受益,但需要额外的处理时间和额外的应用程序大小。

在有根设备中,当然会有风险,但在无根设备中,您甚至可以存储在不可公开读取的共享pref中。您是否希望保护数据,以保护应用程序的合法用户无法获取数据,或者您是否希望为用户提供一种方法来保护其自己的数据免受其他人的攻击,例如窃取设备?第一种是不可能完全阻止的,因为用户可以完全控制他的设备,并且可以根据他的技能从内存或存储器中获取任何信息,并调整整个设备固件,crypto api等。如果用户选择了一个未存储在设备上的密码,则可以实现第二个密码。@zapl我想对应用程序的用户保护数据。如你所说,完全安全是不可能的。但我正在寻找一种方法,如果用户发现他/她将尝试这样做,那么这将是一个巨大的挑战。非常感谢!)回答得好!