简体   繁体   English

如何在iPhone上加密CoreData内容

[英]How can I encrypt CoreData contents on an iPhone

I have some information I'd like to store statically encrypted on an iPhone application. 我有一些信息,我想在iPhone应用程序上静态加密。 I'm new to iPhone development, some I'm not terribly familiar with CoreData and how it integrates with the views. 我是iPhone开发的新手,有些我对CoreData以及它与视图的集成方式并不十分熟悉。 I have the data as JSON, though I can easily put it into a SQLITE3 database or any other backing data format. 我将数据作为JSON,但我可以轻松地将其放入SQLITE3数据库或任何其他支持数据格式。 I'll take whatever is easiest (a) to encrypt and (b) to integrate with the iPhone view layer. 我将采取最简单的方法(a)加密和(b)与iPhone视图层集成。

The user will need to enter the password to decrypt the data each time the app is launched. 每次启动应用程序时,用户都需要输入密码来解密数据。 The purpose of the encryption is to keep the data from being accessible if the user loses the phone. 加密的目的是在用户丢失电话时防止数据被访问。

For speed reasons, I would prefer to encrypt and decrypt the entire file at once rather than encrypting each individual field in each row of the database. 出于速度原因,我宁愿一次加密和解密整个文件,而不是加密数据库每一行中的每个字段。

Note: this isn't the same idea as Question 929744 , in which the purpose is to keep the user from messing with or seeing the data. 注意:这是不一样的想法, 问题929744 ,其目的是让用户从搞乱或看到的数据。 The data should be perfectly transparent when in use. 使用时数据应完全透明。

Also note: I'm willing to use SQLCipher to store the data, but would prefer to use things that already exist on the iPhone/CoreData framework rather than go through the lengthy build/integration process involved. 另请注意:我愿意使用SQLCipher存储数据,但更愿意使用iPhone / CoreData框架上已有的东西,而不是经历冗长的构建/集成过程。

You can encrypt individual properties in your Core Data model entities by making them transformable properties , then creating an NSValueTransformer subclass which will encrypt and decrypt the data for that property. 您可以通过创建可转换属性来加密Core Data模型实体中的各个属性 ,然后创建NSValueTransformer子类,该子类将加密和解密该属性的数据。 While this is not the whole-database decryption that you're looking for, it will have a much lower memory footprint than decrypting an entire database into memory. 虽然这不是您正在寻找的全数据库解密,但它将比将整个数据库解密到内存中的内存占用更少。 Additionally, it will allow the decryption to be done lazily, rather than all up front, so your application will load much faster. 此外,它将允许懒惰地进行解密,而不是预先完成,因此您的应用程序将加载更快。 Depending on the encryption used, I would even expect that the on-disk data accesses for loading each entity would be slower than the decryption process for the properties, so you won't see that much of a performance penalty when accessing the properties. 根据所使用的加密,我甚至会期望用于加载每个实体的磁盘数据访问速度比属性的解密过程慢,因此在访问属性时您不会看到太多的性能损失。

Transformable properties like this are very easy to use, because you read and write to them as normal, while the encryption / decryption goes on behind the scenes. 像这样的可变形属性非常容易使用,因为您可以正常读取和写入它们,而加密/解密在幕后进行。

Do you need to encrypt? 你需要加密吗? Newer iPhones (3Gs, 4, iPad...) encrypt all data on the device. 较新的iPhone(3Gs,4,iPad ......)加密设备上的所有数据。 With a single, hashed, salted password on your app, no one can get to the data without a password. 使用您的应用程序上的单个,哈希,盐渍密码,没有密码,任何人都无法访问数据。 Data is sandboxed from all other apps. 数据来自所有其他应用程序的沙箱。

Data Protection on iOS iOS上的数据保护

I am currently using https://github.com/project-imas/encrypted-core-data to encrypt my coredata store. 我目前正在使用https://github.com/project-imas/encrypted-core-data来加密我的coredata商店。 It is a custom implementation of NSIncrementalStore basically is a community replacement for apple's own persistent store that has an encryption option. 它是NSIncrementalStore的自定义实现,基本上是苹果自己的持久存储的社区替代品,它具有加密选项。 It is a drop-in solution that works. 这是一个有效的插入式解决方案。 You can also take the sqlite file out and decrypt it with whatever passcode you choose in many different clients. 您也可以将sqlite文件取出并使用您在许多不同客户端中选择的任何密码对其进行解密。

The implementation does not have 100% coverage and doesn't allow for some features such as subquery predicates. 实现没有100%的覆盖率,并且不允许某些功能,例如子查询谓词。 I am due to submit my first PR to the repo to hope change that soon ;-). 我将把我的第一个PR提交给回购,希望很快改变;-)。 I almost have it completley working with a very complex coredata app. 我几乎完全可以使用非常复杂的 coredata应用程序。 It also has the added benefit of allowing you direct SQLite access without having to worry about apple's implementation changing on you since you have full access to the source. 它还具有额外的好处,允许您直接访问SQLite,而不必担心苹果的实现会因您对源的完全访问权而改变。

I succeeded in adapting Apple's CustomAtomicStoreSubclass example code for use in a Mac desktop application, resulting in an encrypted NSBinaryStore-style persistent store written as a single file in the filesystem. 我成功地调整了Apple的CustomAtomicStoreSubclass示例代码,以便在Mac桌面应用程序中使用,从而将加密的NSBinaryStore样式持久存储写入文件系统中的单个文件。 My approach: 我的方法:

  • Copy the CustomAtomicStoreSubclass & CustomAtomicStoreSubclassCacheNode class source code into my project and rename them CustomAtomicStoreSubclassCustomAtomicStoreSubclassCacheNode类源代码复制到我的项目中并重命名它们
  • Store the key and initial vector in the Keychain 将密钥和初始向量存储在Keychain中
  • Use the OpenSSL library bundled with Mac OS X 使用与Mac OS X捆绑在一起的OpenSSL库
  • Encrypt NSKeyedArchiver output and write the ciphertext to disc (decryption is the reverse) 加密NSKeyedArchiver输出并将密文写入光盘(解密是相反的)

I intercepted backing store reads & writes in the readFile , metadataForPersistentStoreWithURL:error: , setMetadata:forPersistentStoreWithURL:error: , and save: methods in CustomAtomicStoreSubclass . 我在readFilemetadataForPersistentStoreWithURL:error:setMetadata:forPersistentStoreWithURL:error:拦截了后备存储读取和写入,并在CustomAtomicStoreSubclass save:方法。

The Subclassing Notes for the iPhone's NSAtomicStore Class Reference looks similar to that of Mac OS X's. iPhone的NSAtomicStore类参考的子类注释类似于Mac OS X的子类注释。 Perhaps this approach might also work with the iPhone. 也许这种方法也适用于iPhone。

I know this is an old question, but it's still quite relevant and I recently had to tackle the subject myself. 我知道这是一个老问题,但它仍然非常相关,我最近不得不自己解决这个问题。

Transformable properties are a potential solution, but did not seem to work with NSPredicates, which is a big drawback. 可转换属性是一种潜在的解决方案,但似乎不适用于NSPredicates,这是一个很大的缺点。 I did not pursue the CustomAtomicStoreSubclass approach, but am curious if others have had success with it. 我没有采用CustomAtomicStoreSubclass方法,但我很好奇其他人是否取得了成功。

My concerns were similar to those of the original poster, and I ultimately wound up doing the following: 我的担忧与原始海报的问题类似,最终我做了以下事情:

  1. Decrypt the store to a temp file 将商店解密为临时文件
  2. Load the decrypted store normally 正常加载解密的商店
  3. Migrate the store to an in-memory store 将存储迁移到内存存储中
  4. Delete the unencrypted store 删除未加密的商店

In my case, my store was read-only, but this could be expanded to write the store back out, encrypt it, and delete the unencrypted store once more. 在我的情况下,我的商店是只读的,但这可以扩展为将商店退回,加密并再次删除未加密的商店。 You can also always skip #3 if you have a large store and/or aren't concerned about having an unencrypted file sitting around while your app is running. 如果您有一个大型商店和/或不关心在您的应用运行时有未加密的文件,您也可以跳过#3。

The Core Data file I was working with was ~1MB, and could be encrypted/decrypted very quickly. 我正在使用的核心数据文件大约是1MB,可以非常快速地加密/解密。

"The purpose of the encryption is to keep the data from being accessible if the user loses the phone." “加密的目的是在用户丢失手机时防止数据被访问。”

iOS has had Data Protection since iOS 4, and Core Data has supported this for a long time. 从iOS 4开始,iOS已经拥有数据保护 ,而且Core Data长期以来一直支持这一点。 Data protection is designed for exactly the kinds of scenarios you are interested in. By default, Core Data NSSQLiteStoreType files have NSFileProtectionCompleteUntilFirstUserAuthentication for applications built with the iOS 5 API or later. 数据保护专门针对您感兴趣的各种场景而设计。默认情况下,Core Data NSSQLiteStoreType文件具有针对使用iOS 5 API或更高版本构建的应用程序的NSFileProtectionCompleteUntilFirstUserAuthentication The WWDC 2012 session Protecting the User's Data goes into this topic in much more detail, and recommends using NSFileProtectionComplete . WWDC 2012会话保护用户数据更详细地涉及此主题,并建议使用NSFileProtectionComplete You can use this with Core Data by passing that value in the options dictionary used to open your Core Data NSSQLiteStoreType store. 您可以通过在用于打开Core Data NSSQLiteStoreType存储的选项字典中传递该值,将其与Core Data一起使用。

Example: 例:

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

The broader topic of device security is covered in iOS Device Security iOS设备安全性涵盖了更广泛的设备安全主题

How do I encrypt or decrypt data? 如何加密或解密数据?

"The Certificate, Key, and Trust Services API provides functions for generating symmetric and asymmetric encryption keys, creating and verifying digital signatures, and encrypting keys and nonces. The CommonCrypto library is used for symmetric encryption, hashing, and HMAC operations. Refer to Certificate, Key, and Trust Services Reference and the CC_crypto(3cc) man pages for for more information." “证书,密钥和信任服务API提供了生成对称和非对称加密密钥,创建和验证数字签名以及加密密钥和随机数的功能.CommonCrypto库用于对称加密,散列和HMAC操作。请参阅证书,密钥和信任服务参考以及CC_crypto(3cc)手册页以获取更多信息。“

You can use Trasformables, and I confirm, you cannot use them with predicates, but (and it's worse) you cannot even use 你可以使用Trasformables,我确认,你不能将它们与谓词一起使用,但是(而且更糟)你甚至无法使用

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

if You use predicates.. 如果您使用谓词..

it works fine if You crypt you data using: 如果使用以下方法对数据进行加密,它可以正

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

to crypt data. 加密数据。 (and for example on the simulator.... and move on the project bundle later..) (例如在模拟器上....稍后再移动项目包..)

Encryption is encryption no matter what format your data is in, and you certainly don't need to worry about how anything "integrates with the views." 无论您的数据采用何种格式,加密都是加密的,您当然不必担心“与视图集成”的方式。 All you have to do is decrypt it before you try to read anything meaningful. 在尝试阅读任何有意义的内容之前,您所要做的就是解密它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM