将值保存到磁盘并防止篡改的最佳方法? (没有过顶加密)

时间:2011-08-27 19:20:09

标签: iphone objective-c

我正在编写游戏,我希望高分能够在本地保存,但我不希望用户能够进入plist文件并更改值。什么是让用户很难轻松编辑高分的最佳方法。将值作为NSNumber,然后我写为NSData就足够了吗?

5 个答案:

答案 0 :(得分:3)

AES可能比它的价值更麻烦。就像我尊重Jeff LaMarche一样,这种实施并不好。这对于这个目的来说已经足够了,但除非你明白什么是正确的以及它有什么问题,否则在我看来并不是要复制的东西。我在Properly encrypting with AES with CommonCrypto详细讨论了这个问题,并包括如何正确地进行AES;但是你可能不想在这里正确地做正确的AES麻烦,如果你这样做的话就不会给你带来太大的收获。

我的建议是一个简单的校验和哈希:

- (NSUInteger)checksumForScore:(NSUInteger)score player:(GKPlayer *)player {
  NSString *string = [NSString stringWithFormat:@"%d%@%@", score, [player playerID], kLongRandomPassword];
  return [string hash];
}

然后将校验和与分数一起存储。您将其验证为:

- (BOOL)isValidChecksum:(NSUInteger)checksum forScore:(NSUInteger)score player:(GKPlayer *)player {
  return (checksum == [checksumForScore:score player:player]);
}

我在这里使用GKPlayer playerID来选择一些易于使用的内容,但对于设备所有者在播放时更改并非易事。这样做会使重播攻击变得困难。我不能把我朋友的plist条目与我的plist的超高分复制。当用户更换设备或恢复此设备时,它也非常持久。如果您没有使用GameKit,首先,您可能应该:D和第二,您必须弄清楚是否有其他想要使用的密钥。如果你让用户在某个时候输入它,那么“用户句柄”也会没问题。任何对用户来说都是独一无二的东西,他不会只是复制他的朋友。

Keychain作为一种混淆技术很有意思。甚至合法地阅读也是一种皇家的痛苦,因此官方SDK提供了自己的混淆:D我怀疑这是值得的麻烦,但它是一个“隐藏”少量数据的好地方。

NSCoding甚至没有混淆。任何打算打开plist的人都可以在不到一分钟的时间内读写NSCoding。将此转换为NSData也是如此。将其存储在SQLite或Core Data中也是如此。

@CocoaFu对NSDataWritingFileProtectionComplete的建议很聪明,但我怀疑它会对越狱设备产生任何实际影响。一旦设备解锁,操作系统将为您解密任何文件,因此对于知道设备PIN的人来说,这根本不是障碍。

答案 1 :(得分:2)

使用NSData内置加密保存数据:

- (BOOL)writeToFile:(NSString *)path options:(NSDataWritingOptions)mask error:(NSError **)errorPtr

选项:

NSDataWritingFileProtectionComplete

适用于iOS 4.0及更高版本。

答案 2 :(得分:1)

用户如何编辑plist?他们必须越狱才能访问您应用的文档文件夹。即使我写了一个试图访问你的plist的应用程序,沙箱也阻止了我,除非设备被越狱。我不会为比赛得分而担心,而是把时间花在其他地方。

答案 3 :(得分:0)

如果您真的担心,您可以对数据进行代码加密。 Here是关于如何做到这一点的教程。

我认为NSCoding可能是最简单的赌注。它以非显而易见的方式格式化保存文件,您必须知道您正在做什么才能更改它。

希望有所帮助!

答案 4 :(得分:0)

请看这里:

1)钥匙串服务http://developer.apple.com/library/ios/documentation/Security/Conceptual/keychainServConcepts/iPhoneTasks/iPhoneTasks.html

2)或使用CoreData在sqlite db中保存数据。