CryptoCoding是NSCoding协议的超集,允许轻松无缝地对任何NSCoding兼容对象进行加密。
CryptoCoding旨在与AutoCoding库(https://github.com/nicklockwood/AutoCoding)协同工作,该库可以自动为您的类编写initWithCoder:
和encodeWithCoder:
方法。
CryptoCoding还旨在与BaseModel库(https://github.com/nicklockwood/BaseModel)无缝协作,该库可让您以最小的工作量构建强大的模型层次结构。请在BaseModel存储库中查找(CryptoTodoList)示例,了解这些库如何协同工作。
注:'支持'的意思是该库已经与该版本进行了测试。'兼容'的意思是该库应能在该操作系统版本上运行(即它不依赖任何不可用的SDK功能),但不再对其进行兼容性测试,可能需要调整或修正错误才能正确运行。
从版本1.0.2开始,CryptoCoding需要ARC。如果您想在非ARC项目中使用CryptoCoding,只需将-fobjc-arc编译器标志添加到CryptoCoding.m文件中。要做到这一点,请转到目标设置中的构建阶段选项卡,打开编译源分组,在列表中双击CryptoCoding.m,然后在弹出窗口中键入-fobjc-arc。
如果您希望将整个项目转换为CryptoCoding,请取消注释CryptoCoding.m中的#error行,然后在Xcode中运行编辑 > 重构 > 转换到Objective-C ARC...工具,并确保所有您希望使用ARC的文件都已勾选(包括CryptoCoding.m)。
CryptoCoding是完全线程安全的。
要使用CryptoCoding,只需将CryptoCoding类文件拖放到您的项目中,并添加Apple Security框架。
使用CryptoCoding的最简单方法如下
1) 将NSCoding添加到您的类中,与通常操作一样,可以手动添加initWithCoder:
和encodeWithCoder:
方法,或者使用AutoCoding库(https://github.com/nicklockwood/AutoCoding)来自动添加NSCoding支持。
2) 在您的对象图(将从文件中保存/加载的根对象)中实现CryptoCoding协议。此协议包含一个方法,即CCPassword
,它返回用于加密和解密归档的密码。密码可以是硬编码的,也可以从用户输入或密钥链中检索。
3) 使用CryptoCoder类的archiveRootObject:toFile:
方法保存根对象。然后可以使用unarchiveObjectWithFile:
方法在以后加载对象。
CryptoCoding提供以下类接口
CryptoCoding分类扩展NSData,包含以下方法
- (NSData *)AESEncryptedDataWithPassword:(NSString *)password IV:(NSData **)IV salt:(NSData **)salt error:(NSError **)error version:(float)version;
此方法接收一个密码,并使用AES128算法返回数据的加密副本。请注意IV(初始向量)和盐参数。这些参数是指向将被该方法返回的值的指针。保存盐和IV值非常重要,因为您需要在稍后解密数据时使用它们。只有密码是保密的 - 盐和IV值的文本可以与加密数据一起存储。将版本参数传递为0,使用默认加密版本。如果您需要提供遗留支持,请使用1.0。
- (NSData *)AESDecryptedDataWithPassword:(NSString *)password IV:(NSData *)IV salt:(NSData *)salt error:(NSError **)error version:(float)version;
此方法接收一个密码、盐和IV值,并返回数据的未加密副本。密码、盐和IV必须与最初创建数据时使用的那些一致。版本值应与最初加密数据时使用的版本相匹配(1.0或2.0)。
CryptoArchive类用于包装加密数据以及盐和IV值和一些其他有用信息。除非您希望编码一个不遵循CryptoCoding协议的对象,否则通常不需要直接使用此类。
- (id)initWithRootObject:(id)rootObject password:(NSString *)password;
从NSCodable对象和密码创建一个新的CryptoArchive。与CryptoCoder方法不同,被编码的对象不要求遵循CryptoCoding协议(尽管它仍然需要遵循NSCoding)。这可能是有用的,如果您想编码一个通用的集合对象,如NSArray或NSDictionary。
- (id)unarchiveRootObjectWithPassword:(NSString *)password;
从CryptoArchive解密原始对象并将其返回。CryptoArchives是有版本的。如果归档版本号的整数部分大于当前库的CryptoCodingVersion
,则解密过程将失败,并且该方法将返回nil。同样的情况也适用于密码与创建归档时使用的密码不匹配。
CryptoCoder实现了以下方法,这些方法与NSKeyedArchiver和NSKeyedUnarchiver类的方法相对应。请注意,CryptoCoder的所有方法都是静态的 - 您不需要实例化CryptoCoder类。
+ (id)unarchiveObjectWithData:(NSData *)data;
此方法解码CryptoCoded数据对象,并解包存储的对象。解密文件的密码将通过在文件中包含的类上调用CCPassword
方法来获取。如果类未实现此方法或返回的值与用于解密文件的密码不匹配,则解包过程将失败。如果存档未被加密,则将无声返回未加密的对象,因此可以使用此方法无缝加载已加密或未加密的存档。
+ (id)unarchiveObjectWithFile:(NSString *)path;
与上述方法相同,但此方法接受一个序列化数据文件的路径而不是原始NSData对象。
+ (NSData *)archivedDataWithRootObject:(id)rootObject;
此方法使用NSCoding协议将rootObject存档,然后使用AES128算法加密它。加密对象的密码将通过在rootObject类上调用CCPassword
方法来获取。如果rootObject未实现CCPassword
方法,则此方法将抛出一个异常。
+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path;
与上述方法相同,但将生成的加密数据直接写入路径参数指定的文件。
+ (void)setClassName:(NSString *)codedName forClass:(Class)cls;
+ (NSString *)classNameForClass:(Class)cls;
+ (void)setClass:(Class)cls forClassName:(NSString *)codedName;
+ (Class)classForClassName:(NSString *)codedName;
这些方法用于在编码或解码对象时指定类名替换,并且当管理应用程序版本间的升级以及在类可能被重命名时非常有用。这些方法分别包装了NSKeyedArchiver/Unarchiver的等效方法,因此你在调用CryptoCoder或NSKeyedArchiver/Unarchiver都没有区别。
版本 1.1
版本 1.0.1
版本 1.0