一个iOS开发本地资源文件的加密方案

版权声明:欢迎大家积极分享!交流。关注我~ https://blog.csdn.net/qinqi376990311/article/details/81536052

一个iOS开发本地资源文件的加密方案

在开发中,不可避免的要有一些本地资源文件要放在 mainBundle 里面,比如 plist 文件、json文件、视频、图片 等等这样的。那如果能拿到 ipa 文件,直接解包就可以看到我们 mainBundle 里面的文件。如此一来,这些资源就会暴露无遗。

我大概在网上搜了一下,有用 AES 加解密的,各种,甚至还编写了简单的 MacApp 方便操作。如此当然安全性是很高的,同时也容易带来性能问题。

我想到了一个很简单的办法。其实就是利用 归档。

plist 要单独处理,因为 plist 有可能是数组,也有可能是字典。
其他文件可以统一按照二进制文件处理。

打开Xcode,Command + Shift + N 创建一个新的 Command Line Tool 工程,用 Command Line Tool 就足够啦。

在我们项目的工程中,把所有的需要加密的资源文件提取出来,并在工程中不要引用他们。本例我放在 Resources 文件夹下
工程中资源文件

接下来在我们刚创建的 Command Line Tool 工程中,把文件夹拖进来。注意:这里选择 Create folder references
导入工程

导入之后,看到的应该是蓝色的文件夹,就没问题了
导入之后

接下来,开始编辑 main.m 文件:

#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]];
}

附:

查看当前工程所有会出现在 mainBundle 的资源文件:
资源文件

图片资源的问题:
如果是有@2x 和 @3x 的区分,那可能你在取出图片的时候需要判断[UIScreen mainScreen].scale 是 2 还是 3 ,从而取不同的 NSData

文件命名的问题:
我选择 data 作为扩展名,当然也可以随便输入的。另外,导出的能是这样的文件名:“BankBin.plist.data”,有两个扩展名,可以把.plist去掉,这样看起来更规范一些。即 “BankBin.data”

有的小伙伴可能对 蓝色文件夹 和 黄色文件夹 有什么区别,存在困惑,请移步:
https://blog.csdn.net/qinqi376990311/article/details/81536091

猜你喜欢

转载自blog.csdn.net/qinqi376990311/article/details/81536052