更新:在 iOS 6 中,可能需要通过使用需要在 iOS 配置文件中的 App ID 上配置的权利来为您的应用程序提供数据保护。我还没有测试过,这是我能找到的最好的信息https://devforums.apple.com/message/707939#707939
我对此事的调查使我相信很难确定设备上是否启用了数据保护。
NSFileProtectionKey
通过将文件属性设置为启用文件保护NSFileProtectionComplete
例如,要创建一个受保护的文件,您可以运行如下代码:
[[NSFileManager defaultManager] createFileAtPath:[self filePath]
contents:[@"super secret file contents" dataUsingEncoding:NSUTF8StringEncoding]
attributes:[NSDictionary dictionaryWithObject:NSFileProtectionComplete
forKey:NSFileProtectionKey]];
不幸的是,即使设备上未启用数据保护(或者如果代码在数据保护不可用的模拟器上运行),此代码也将毫无错误地执行。
更糟糕的NSFileProtectionComplete
是,无论文件是否受保护,都会设置该属性。以下:
self.fileProtectionValue = [[[NSFileManager defaultManager] attributesOfItemAtPath:[self filePath]
error:NULL] valueForKey:NSFileProtectionKey];
NSLog(@"file protection value: %@", self.fileProtectionValue);
file protection value: NSFileProtectionComplete
无论是否启用数据保护都会吐出。
我可以使用两种方法来发现文件保护是否按预期工作。不幸的是,这些方法都不适用于检测是否在现场的设备上启用了数据保护。
这两种方法的工作原理是,如果设备被锁定,则无法读取受保护的文件。
方法一涉及使用计时器在设备锁定后尝试读取文件,但在您的应用程序继续运行时:
[self performSelector:@selector(doReload) withObject:nil afterDelay:20];
- (void)doReload {
NSLog(@"protected data available: %@",[[UIApplication sharedApplication] isProtectedDataAvailable] ? @"yes" : @"no");
NSError *error;
self.fileContents = [NSString stringWithContentsOfFile:[self filePath]
encoding:NSUTF8StringEncoding
error:&error];
NSLog(@"file contents: %@\nerror: %@", self.fileContents, error);
}
如果您运行上述代码并锁定受数据保护的设备,它将吐出:
protected data available: no
file contents: (null)
error: Error Domain=NSCocoaErrorDomain Code=257 "The operation couldn’t be completed. (Cocoa error 257.)" UserInfo=0x16e110 {NSFilePath=/var/mobile/Applications/D71F1F1F-6C25-4848-BB1F-51539B47EC79/Documents/protected_file, NSUnderlyingError=0x16e010 "The operation couldn’t be completed. Operation not permitted"}
20 秒的延迟是必要的,因为在启用数据保护的设备被锁定后,有 10 秒左右的宽限期,受保护的数据仍然可用。
第二种方法是在应用程序中创建一个受保护的文件,退出应用程序,锁定设备,等待 10 秒,然后使用 XCode 管理器下载应用程序的内容。这将产生一条错误消息,并且受保护的文件将为空。
如果上述任一测试未能按描述运行,则数据保护未启用,或者您的文件保护代码未正确实现。
因为在将机密信息写入磁盘之前,我没有找到任何方法来验证应用程序中是否启用了数据保护,所以我向 Apple 提交了功能增强请求,以便能够将应用程序标记为需要启用数据保护. (rdar://10167256)
Apple 确实通过其移动设备管理 (MDM) API 提供了解决方案,该 API 与第三方服务器相结合,可用于强制执行需要在设备上启用数据保护的策略。