防止在iPhone中对savedata进行欺骗

防止在iPhone中对savedata进行欺骗,iphone,Iphone,我们可以使用sqlite、nsuserdefaults或普通文件系统在iPhone上保存游戏数据。这些数据通常存储在Documents目录中,但是Documents目录下的文件可以很容易地修改,而无需越狱。(事实上,一些作弊的分数之前已经发布到服务器上) 我考虑过一些通过修改保存数据来防止作弊的方法 加密文件 只需加密数据文件并在读取时解密即可。它看起来很安全,但如果游戏需要频繁更新游戏数据,性能将被牺牲 SQLite加密 sqlite有一些加密扩展库。问题在于成本和许可证 验证器/校验和 存

我们可以使用sqlite、nsuserdefaults或普通文件系统在iPhone上保存游戏数据。这些数据通常存储在Documents目录中,但是Documents目录下的文件可以很容易地修改,而无需越狱。(事实上,一些作弊的分数之前已经发布到服务器上)

我考虑过一些通过修改保存数据来防止作弊的方法


加密文件 只需加密数据文件并在读取时解密即可。它看起来很安全,但如果游戏需要频繁更新游戏数据,性能将被牺牲

SQLite加密 sqlite有一些加密扩展库。问题在于成本和许可证

验证器/校验和 存储保存数据的校验和,并使用它检测欺骗。如果由于某种原因保存校验和失败,可能会导致误报结果

钥匙链 将数据存储到钥匙链中。但是我们不能使用sqlite。在钥匙链中存储大数据可以吗



每个想法都有缺点。您能给我一些建议吗?

您可以将数据保存在NSLibraryDirectory的子文件夹中,而不是NSDocumentsDirectory。用户无法通过iTunes查看或编辑NSLibraryDirectory。

设计中的一个缺陷似乎是您信任本地数据。相反,我建议您将本地数据视为不安全的用户数据。这样,用户就可以随心所欲地操作它,但您永远不会将它发送到服务器进行发布

当用户完成游戏时,让游戏立即将分数发送给服务器。如果您愿意,您的服务器可以发回一个签名副本(散列),您可以将其以任何格式保存到任何地方。在您的游戏中,您可以在在线时发生的分数旁边添加一个小的“验证分数”徽章。如果已验证的分数被操纵,则哈希将不起作用,并且(无论如何,在本地)他们将失去分数

如果用户处于脱机状态,则无法验证其分数。您仍然可以将其与所有签名分数一起保存在本地,但根本不必担心同步坏数据。永远不要向服务器发送从本地文件系统读取的数据


从用户体验的角度来看,这可能并不理想,但您可以通过告诉用户“如果您在获得高分时连接到互联网,您的分数将被验证并公布在全球排行榜上”或类似的方式来构建它。我相信你能想出一个办法来处理它。

如果你想走这条路的话,有一些非常轻的密码,如果几乎不可破解的话。我在过去使用了替换密码的一种变体,我用随机数对值进行异或运算。这些东西几乎是牢不可破的(特别是如果你每次都改变它——没有什么比每次都得到不同的结果更让黑客沮丧的了:)

数据越小,就越容易被破解。没有什么比嗅探一个网络并发现10位数字编码在一个4096位的随机数字块中更令人沮丧的了


根据数据的大小,您可以使用不同的密码对不同的部分进行编码-编码/解码会很轻,但黑客很痛苦。

为什么校验和会失败?顺便说一句,即使没有狗,只要贴上一个写着“当心狗”的牌子,很多人也会被拒之门外。标签上写着“作弊者将被排除在游戏之外”可能会有所帮助,而且不会花费任何费用。我会对数据库进行校验和,并将该值存储在keychain中,然后在启动时验证keychain=db checksum、从后台返回等。如果我们以非原子方式保存数据和校验和,校验和将失败。我们需要交易基础设施来完成这项工作。不幸的是,有一些工具可以将iPhone安装为磁盘驱动器,我们可以使用它们修改设备上的任何数据(甚至是库目录中的数据):(没错。我会把时间花在轻量级加密上。我几乎同意,离线记录的不信任分数是明智的选择之一。但我们不能不信任其他游戏数据,如用户的位置、物品拥有或任何标志,因为如果我们不信任它们,游戏状态将崩溃,即使这些数据被删除,也可以记录验证分数。)由用户修改。听起来你想解决两个问题:1)用户正在修改他们的游戏保存数据(作弊)。2)你想防止被篡改的数据发布到你的服务器。要解决#1,您可以像这里的人所描述的那样对保存格式进行模糊处理或加密。如果不了解您的特定应用程序的更多信息,就很难提出一种方法来满足您的需要,因为我们不知道您的应用程序和服务器上发生了什么。为了解决#2,我认为上面的建议仍然有效,但我也不知道问题的全部背景。这似乎是一个成本效益高的解决方案。但是我可以在SQLite数据库中使用这个解决方案吗?是的,但它意味着将事物存储为二进制数据。这有点不方便,但不是一项困难的任务。一个很好的方面是,你可以使密码简单或恶劣,因为你想。您甚至可以将密钥存储在SQLite数据库中(只是不要称之为密钥,这样也很难准确地确定哪些数字是密钥)。有关实现此方法的一些代码,请参见此处: