【问题标题】:How can I encrypt CoreData contents on an iPhone如何在 iPhone 上加密 CoreData 内容
【发布时间】:2010-12-11 07:52:24
【问题描述】:

我想在 iPhone 应用程序上静态加密存储一些信息。我是 iPhone 开发的新手,有些我不太熟悉 CoreData 以及它如何与视图集成。我有 JSON 格式的数据,但我可以轻松地将其放入 SQLITE3 数据库或任何其他支持数据格式。我将采用最简单的方法 (a) 加密和 (b) 与 iPhone 视图层集成。

每次启动应用程序时,用户都需要输入密码才能解密数据。加密的目的是在用户丢失手机时防止数据被访问。

出于速度原因,我更愿意一次加密和解密整个文件,而不是加密数据库每一行中的每个单独字段。

注意:这不是Question 929744 相同的想法,其目的是防止用户弄乱或看到数据。数据在使用时应该完全透明。

另请注意:我愿意使用SQLCipher 来存储数据,但更愿意使用 iPhone/CoreData 框架中已经存在的东西,而不是经历冗长的构建/集成过程。

【问题讨论】:

    标签: iphone encryption core-data


    【解决方案1】:

    您可以通过将它们设为transformable properties 来加密 Core Data 模型实体中的各个属性,然后创建一个 NSValueTransformer 子类来加密和解密该属性的数据。虽然这不是您要查找的整个数据库解密,但与将整个数据库解密到内存相比,它的内存占用要低得多。此外,它将允许延迟完成解密,而不是全部预先完成,因此您的应用程序将加载得更快。根据使用的加密,我什至希望加载每个实体的磁盘数据访问会比属性的解密过程慢,因此在访问属性时不会看到那么多的性能损失。

    像这样的可转换属性非常易于使用,因为您可以正常读写它们,而加密/解密在幕后进行。

    【讨论】:

    • 如果 (a) 更容易且 (b) 更快的话,我非常乐意进行懒惰的、单独的解密而不是大规模解密。
    • 你要解密多少?将解密的所有内容放入内存可能不可行,具体取决于设备模型的限制。此外,如果您有大量数据,用户是否可以坐在那里等待完全解密? Brad 的设计方法肯定更加透明(即,可以进行故障排除),并且在您的模型更改时可能会更加灵活。只进行必要的解密和核心数据故障查找可能会更快,而不是一次获取和解密所有内容。分析肯定会告诉你。
    • 是的,但请注意,使用对称密码和短属性,它开始变得非常不安全。
    • @Brad Larson,您如何建议将解密的值缓存在内存中以避免每次获取请求时解密它们?
    • 如果每个属性都是可转换属性,是否可以对核心数据执行搜索操作?
    【解决方案2】:

    您需要加密吗? 较新的 iPhone(3G、4、iPad...)对设备上的所有数据进行加密。在您的应用程序上使用一个经过哈希处理的加盐密码,没有密码就没有人可以访问数据。数据来自所有其他应用程序的沙盒。

    Data Protection on iOS

    【讨论】:

    • 这是正确答案。无需手动执行此操作;见nickharris.wordpress.com/2010/07/14/…
    • 如果用户没有在设备上设置密码,其他人可以通过应用程序可能无法接受的方式获取数据。
    • 这不是正确的答案。这种方法是为了保护用户数据不被利用。系统工具存在缺陷,即它们不能保护我们(发布者)的数据。为此,开发人员需要手动完成。
    • 当你在 Itunes 中下载应用程序时的例子,在 .IPA 文件中有所有 SQLite 后端。因此,您可以在安装到“安全”设备之前获取它。
    • 在没有越狱的世界里,这个答案是正确的
    【解决方案3】:

    “加密的目的是在用户丢失手机时防止数据被访问。”

    iOS 从 iOS 4 开始就有Data Protection,Core Data 已经支持这个功能很长时间了。数据保护专为您感兴趣的场景而设计。默认情况下,Core Data NSSQLiteStoreType 文件具有NSFileProtectionCompleteUntilFirstUserAuthentication,用于使用 iOS 5 API 或更高版本构建的应用程序。 WWDC 2012 会议Protecting the User's Data 更详细地讨论了这个主题,并建议使用NSFileProtectionComplete。您可以通过在用于打开您的 Core Data NSSQLiteStoreType 存储的选项字典中传递该值来将此值与 Core Data 一起使用。

    例子:

    NSDictionary *storeOptions = @{ NSPersistentStoreFileProtectionKey : NSFileProtectionComplete };
    if (![coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self storeURL] options:storeOptions error:&error]){
    

    iOS Device Security 涵盖了更广泛的设备安全主题

    【讨论】:

    • 据我了解,这将在不使用 SQLite 文件时对其进行加密,但是当核心数据库打开时,SQLite 文件不会被加密。对吗?
    • @Peter 是的,你是对的。这些设置仅适用于设备上有密码的情况。
    • 加密的目的不止于此。例如。作为应用开发者...我想让用户(包括设备所有者)看不到他们数据库的内容。
    【解决方案4】:

    我目前正在使用https://github.com/project-imas/encrypted-core-data 来加密我的核心数据存储。它是NSIncrementalStore 的自定义实现,基本上是苹果自己的具有加密选项的持久性存储的社区替代品。这是一个有效的插入式解决方案。您还可以取出 sqlite 文件并使用您在许多不同客户端中选择的任何密码对其进行解密。

    该实现没有 100% 的覆盖率,并且不允许使用某些功能,例如子查询谓词。我将提交我的第一个 PR 到 repo 以希望尽快改变 ;-)。我几乎可以完全使用 非常复杂 coredata 应用程序。它还有一个额外的好处是允许您直接访问 SQLite,而不必担心苹果的实现会改变您,因为您可以完全访问源代码。

    【讨论】:

    • 我们也在使用相同的加密核心数据类进行测试。但是,您如何使用它处理迁移?特别是progressive migrations?
    • encrypted-core-data 似乎不再被维护,最后一次提交是在 2017 年 github.com/project-imas/encrypted-core-data/graphs/…,并且文档指出它“已知在 iOS 版本 6.0 到 9.2 上成功运行。”有谁知道维护相同功能的项目?
    【解决方案5】:

    我成功地调整了 Apple 的 CustomAtomicStoreSubclass 示例代码以用于 Mac 桌面应用程序,从而在文件系统中生成了一个加密的 NSBinaryStore 风格的持久性存储库。我的做法:

    • CustomAtomicStoreSubclass & CustomAtomicStoreSubclassCacheNode 类源代码复制到我的项目中并重命名
    • 将密钥和初始向量存储在钥匙串中
    • 使用与 Mac OS X 捆绑的 OpenSSL 库
    • 加密 NSKeyedArchiver 输出并将密文写入磁盘(解密是相反的)

    我在CustomAtomicStoreSubclassreadFilemetadataForPersistentStoreWithURL:error:setMetadata:forPersistentStoreWithURL:error:save: 方法中截获了后备存储读取和写入。

    iPhone 的 NSAtomicStore 类参考的子类化注释看起来与 Mac OS X 的相似。也许这种方法也适用于 iPhone。

    【讨论】:

    • 听起来是个有趣的方法。我试试看。
    【解决方案6】:

    我知道这是一个老问题,但它仍然很相关,我最近不得不自己解决这个问题。

    可转换属性是一种潜在的解决方案,但似乎不适用于 NSPredicates,这是一个很大的缺点。我没有追求 CustomAtomicStoreSubclass 方法,但很好奇其他人是否已经成功。

    我的担忧与原发帖者的相似,最终我做了以下事情:

    1. 将存储解密为临时文件
    2. 正常加载解密后的存储
    3. 将存储迁移到内存存储
    4. 删除未加密的存储

    在我的情况下,我的存储是只读的,但可以扩展以将存储写回、加密并再次删除未加密的存储。如果您拥有大型商店和/或不担心在您的应用运行时存在未加密的文件,您也可以随时跳过第 3 条。

    我使用的 Core Data 文件约为 1MB,可以非常快速地加密/解密。

    【讨论】:

    • 当您将存储迁移到内存存储时,如果攻击者杀死您的应用程序会发生什么?他将拥有您的数据副本。
    【解决方案7】:

    How do I encrypt or decrypt data?

    “证书、密钥和信任服务 API 提供了用于生成对称和非对称加密密钥、创建和验证数字签名以及加密密钥和随机数的功能。CommonCrypto 库用于对称加密、散列和 HMAC 操作。有关详细信息,请参阅 Certificate, Key, and Trust Services ReferenceCC_crypto(3cc) 手册页。”

    【讨论】:

    • 这不是“如何在 iOS 中加密数据库”问题的答案
    【解决方案8】:

    您可以使用 Trasformables,我确认,您不能将它们与谓词一起使用,但是(更糟糕的是)您甚至不能使用

    ... = [self primitiveValueForKey:@"crypted_data"];

    如果你使用谓词..

    如果您使用以下方法加密数据,它可以正常工作:

    [self setPrimitiveValue:cryptedPsw forKey:@"crypted_data"];
    

    加密数据。 (例如在模拟器上.. 稍后继续项目包..)

    【讨论】:

      【解决方案9】:

      无论您的数据采用什么格式,加密就是加密,您当然不必担心任何东西如何“与视图集成”。您所要做的就是在尝试阅读任何有意义的内容之前对其进行解密。

      【讨论】:

      • 让我试着澄清一下:加密和解密数据的方法有很多。我想知道什么最适合 iPhone 世界。什么摩擦力最小?
      猜你喜欢
      • 2013-03-08
      • 1970-01-01
      • 2010-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-21
      相关资源
      最近更新 更多