2019-06-13iOS开发本地资源文件的加密方案
https://blog.csdn.net/fdipzone/article/details/20413631
一个iOS开发本地资源文件的加密方案
https://blog.csdn.net/qinqi376990311/article/details/81536052
我大概在网上搜了一下,有用 AES 加解密的,各种,甚至还编写了简单的 MacApp 方便操作。如此当然安全性是很高的,同时也容易带来性能问题。
我想到了一个很简单的办法。其实就是利用 归档。
plist 要单独处理,因为 plist 有可能是数组,也有可能是字典。
其他文件可以统一按照二进制文件处理。
打开Xcode,Command + Shift + N 创建一个新的 Command Line Tool 工程,用 Command Line Tool 就足够啦。
在我们项目的工程中,把所有的需要加密的资源文件提取出来,并在工程中不要引用他们。本例我放在 Resources 文件夹下
接下来在我们刚创建的 Command Line Tool 工程中,把文件夹拖进来。注意:这里选择 Create folder references
导入之后,看到的应该是蓝色的文件夹,就没问题了
#import <Foundation/Foundation.h>
NSString * OutputFilePath(NSString *fileName) {
//加密之后的文件输出路径,这里我是输出到桌面
return [NSString stringWithFormat:@"/Users/#这里替换成你的用户名#/Desktop/%@.data", fileName];
}
NSString * InputFilePath(NSString *fileName) {
//资源文件路径,其实就是那个 Resources 文件夹的路径
return [NSString stringWithFormat:@"/Users/#这里替换成你的用户名#/Desktop/#这里是你主项目的名称#/Resources/%@", fileName];
}
/**归档二进制文件*/
void EncryptionDataFiles(NSArray *names) {
[names enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSData *data = [NSData dataWithContentsOfFile:InputFilePath(obj)];
[NSKeyedArchiver archiveRootObject:data toFile:OutputFilePath(obj)];
}];
}
/**归档数组类型的Plist文件*/
void EncryptionArrayPlistFiles(NSArray *names) {
[names enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSArray *array = [NSArray arrayWithContentsOfFile:InputFilePath(obj)];
[NSKeyedArchiver archiveRootObject:array toFile:OutputFilePath(obj)];
}];
}
/**归档字典类型的Plist文件*/
void EncryptionDictionaryPlistFiles(NSArray *names) {
[names enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSDictionary *dic = [NSDictionary dictionaryWithContentsOfFile:InputFilePath(obj)];
[NSKeyedArchiver archiveRootObject:dic toFile:OutputFilePath(obj)];
}];
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSArray *names = @[@"BankBin.plist"];
// EncryptionDataFiles(names);
// EncryptionArrayPlistFiles(names);
// EncryptionDictionaryPlistFiles(names);
}
return 0;
}
编辑好之后,Command + R 就可以在输出目录上找到我们加密之后的文件了~
然后我们在主工程中的某目录下,导入我们刚才输出的文件,所以这时候,加密之后的 data 文件,就会出现在 Copy Bundle Resources 里面了,也就是之后的 mainBundle 里面。
那么在主工程中要使用这些文件,需要解密。这里我用了内联函数,我写在 PrefixHeader.pch 中
NS_INLINE id LocalFile(NSString *name) {
//为什么用 id 类型呢,因为返回结果有可能是 NSData ,也可能是 NSArray, 也可能是 NSDictionary 完全取决于当初你加密之前是什么类型的。
return [NSKeyedUnarchiver unarchiveObjectWithFile:[[NSBundle mainBundle] pathForResource:name ofType:nil]];
}
图片资源的问题:
如果是有@2x 和 @3x 的区分,那可能你在取出图片的时候需要判断[UIScreen mainScreen].scale 是 2 还是 3 ,从而取不同的 NSData
文件命名的问题:
我选择 data 作为扩展名,当然也可以随便输入的。另外,导出的能是这样的文件名:“BankBin.plist.data”,有两个扩展名,可以把.plist去掉,这样看起来更规范一些。即 “BankBin.data”