26

Just saw the Session 209 - Securing Application Data from de 2010 WWDC.

The keynote explains a lot of things, including the way you can set data protection attributes to your files (NSFileProtectionComplete, NSFileProtectionNone) and how to decide which protection is best for your case.

I just implemented it, but can't figure out how to test if the security is on, any ideas?

In addition, I have a sql lite database that needs to be accessed in background from time to time, and this method of data protection seems to be not good enough.. any link or tutorial that guide me through the best db protection? (found sql cipher but is kinda heavy to add in a evoluted project)

Thanks!

4

7 回答 7

23

更新:在 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 与第三方服务器相结合,可用于强制执行需要在设备上启用数据保护的策略。

于 2011-09-22T13:56:02.000 回答
10

您可以使用iExplorer应用程序来检测您的文件是否已加密。iExplorer 可让您浏览 iPhone/iPad 的文件系统,并打开文件(当然您的设备必须插入 Mac)。

当设备被锁定时,无法正确读取文件。

于 2012-04-30T14:33:36.100 回答
8

NSFileManager类文档:

该文件以加密格式存储在磁盘上,并且在设备锁定或启动时无法读取或写入。

您只需在设置文件属性时传递常量。

当使用 writeToFile:options:error: 方法将 NSData 对象的内容写入磁盘时,包括 NSDataWritingFileProtectionComplete 选项。

使用 NSFileManager 的 setAttributes:ofItemAtPath:error: 方法将 NSFileProtectionKey 属性(带有 NSFileProtectionComplete 值)添加到现有文件

http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/StandardBehaviors/StandardBehaviors.html

编辑(确定受保护文件的可用性)

只有在设备解锁时才能访问受保护的文件。因为应用程序可能会在设备被锁定时继续运行,所以您的代码应该准备好处理受保护文件随时变得不可用的可能性。UIKit 框架提供了跟踪当前是否启用数据保护的方法。

*

  Use applicationProtectedDataWillBecomeUnavailable: and applicationProtectedDataDidBecomeAvailable: methods and use them to track changes to the availability of protected data.
*

  An application can register for the UIApplicationProtectedDataWillBecomeUnavailable and UIApplicationProtectedDataDidBecomeAvailable notifications.
*

  The protectedDataAvailable property of the shared UIApplication object indicates whether protected files are currently accessible. 

任何使用受保护文件的应用程序都应该实现应用程序委托方法。当调用 applicationProtectedDataWillBecomeUnavailable: 方法时,您的应用程序应立即关闭任何受保护的文件并避免再次使用它们,直到调用 applicationProtectedDataDidBecomeAvailable: 方法。在受保护文件不可用时访问受保护文件的任何尝试都将失败。

验证越狱设备上的文件保护

更进一步,如果您想测试精确文件的文件保护,那么您需要一个越狱设备。为此,以下是(非详细)步骤:

1)越狱iOS设备

2)通过 Cydia 安装 Open SSH(这是从该设备远程访问文件所必需的)(https://cydia.saurik.com/openssh.html

3) 从您的计算机(使用 Mac 客户端或终端)以 root 用户身份登录到您的设备。

要查找应用程序目录和文件的位置,有多种方法。要么你可以

  • grep应用程序的进程(例如ps ax | grep YourAppName) - 确保应用程序正在设备上运行以获取进程详细信息。它应该给出应用程序包的位置
  • 或者,您也可以使用find您感兴趣的搜索特定文件。例如。find / -type f -name YouAppName.sqlite. 它应该提供设备上的文件位置。

从这里,当手机被密码锁定时,您可以尝试查看文件是否真的可以访问;或不。- 您可以简单地运行cat YouAppName.sqlite以查看内容是否可访问。Ia f 文件受保护,它应该显示

不允许操作

错误; 否则如果会显示文件的内容。

同样,如果您真的想检查单个文件的文件保护,这是必需的。如果权利和功能设置正确,则验证权利应该足以保护文件。

在侧节点上,诸如 iExplorer 之类的文件浏览器工具对 FileProtection 的验证没有多大帮助,因为此类工具要求设备处于“受信任”模式,因此它们有权访问您的设备/应用程序的内容。

祝你好运!

于 2011-03-01T14:40:53.163 回答
7

可以在 Xcode 中进行测试:

  1. 删除并重新安装您的应用
  2. 在您的 iOS 设备上,转到“设置”>“密码”并确保“需要密码”设置为“立即”
  3. 锁定手机并等待 20 秒
  4. 在 Xcode 上转到窗口 > 设备
  5. 选择您要测试的应用
  6. 单击设置齿轮并选择“下载容器”
  7. 右键单击下载的 .xcappdata 文件并选择“显示包内容”。您可以在此处查看的任何内容均未加密NSFileProtectionComplete
  8. 解锁手机并重复步骤 3-6。以前没有出现但您现在可以查看的文件已成功加密。

在此处输入图像描述

于 2016-04-13T11:29:55.943 回答
4

文件保护可以在每个文件或每个目录的基础上启用,也可以为整个应用程序启用(使用权利和配置文件)。要确定文件或目录是否受保护,请检查数据保护密钥的文件系统属性。即使它是设置为受保护的父目录,这也应该是有效的:

- (BOOL) isProtectedItemAtURL:(NSURL *)URL {
    BOOL            result                      = YES;
    NSDictionary    *attributes                 = nil;
    NSString        *protectionAttributeValue   = nil;
    NSFileManager   *fileManager                = nil;

    fileManager = [[NSFileManager alloc] init];
    attributes = [fileManager attributesOfItemAtPath:[URL path] error:&error];
    if (attributes != nil){
        protectionAttributeValue = [attributes valueForKey:NSFileProtectionKey];
        if ((protectionAttributeValue == nil) || [protectionAttributeValue isEqualToString:NSFileProtectionNone]){
            result = NO;
        }
    } else {
        // handle the error
    }
    return result;
}

为了确定受保护的内容是否可用,UIApplication 提供了一种查询保护状态的方法,isProtectedDataAvailable. 将它与上述方法一起使用将允许您确定特定文件或目录是否可用:

- (BOOL) isItemAtURLAvailable:(NSURL *)URL {
    BOOL            result                      = NO;

    if ([self isProtectedItemAtURL:URL]){
        // Item is protected
        if ([[UIApplication sharedApplication] isProtectedDataAvailable]){
            // Protected content is available
            result = YES;
        }
    } else {
        result = YES;
    }

    return result;
}
于 2014-09-12T01:04:16.227 回答
3

我认为您不再可以使用基于计算机的工具和未越狱的 iPhone 来测试数据保护 - 也许您过去可以。请在此处查看我的答案,了解测试数据保护的更新方法:https ://stackoverflow.com/a/40044841/1165843

于 2016-10-14T13:52:11.750 回答
0

对于完整的测试,我建议使用 iDB ( https://github.com/dmayer/idb ) 等工具在您的 iOS 应用程序上执行渗透测试,如本指南中所述。与您相关的可能还有此 iOS 安全测试备忘单。

于 2015-10-12T10:36:32.380 回答