最简单最高效的AB包加密方法
对于资源加密的思考
很多人认为ab包不需要加密,但是这样的人我认为,他思考问题的方式是片面的且狭隘。
是否加密应该根据项目本身的资源价值来决定。是否提高资源的破解难度,比如对于一个没什么价值的项目,也没有人会想要去拿你的资源,自然不需要。但是比如像闪耀暖暖这样,资源密集且开发代价较高的项目,资源应该在一定程度上保护起来,使得破解的代价也得到提高。当然,对于破解高手而言,破解只是时间问题。这里主要的目标还是提高破解的代价。
古老的加密方法:二进制加密
在2013年,曾经写过一个文档(Unity3d服务器资源加密,其实是ab包加密),当时由于unity提供的API比较少,所以当时的方法是将ab包作为bytes数据进行加密,加载时读取文件数据,解密之后,通过LoadFromMemory进行加载。虽然这种方式是有效的,但是很显然,加载时间和内存的问题让我们困扰好久。
裸奔的资源
随着Unity的普及,现在已经越来越多的项目使用AB包,但是大部分都是没有加密的。比如某IP侵权的app,可以通过或者Unity内置的AssetBundleBrower直接看到ab包的所有资源
更甚者可以通过AssetStudio直接看到ab包的所有资源,图片,音频,动画,文本,CG视频等等(蒙皮动画目前不行),并且导出。
如果会写点代码,还可以在unity中,直接实例化出来,然后另存为Prefab,这样虽然无法获得fbx(其实fbx开源,自己反推写入数据也可以导出fbx),但是我们可以获得完整的Prefab,设置内含了蒙皮信息。这样可以轻松获得所有的数据,贴图,音频,视频,模型,材质,蒙皮,动画等等
所以,没有加密的资源和裸奔没有什么差别。
二进制加密优化
那么ab加密,上述的加密,有什么优化的方法呢。方法很多,雨松在2019年的一篇文档(Unity3D研究院之加密Assetbundle不占内存(一百零五))提到利用Unity2017.2提供的新API:AssetBundle.LoadFromStream可以实现没有内存额外消耗的方法。
一个更简单有效的加密方式
其实我们用的API有个参数offset就可以解决加密的问题
public static AssetBundle LoadFromFile(string path, uint crc, ulong offset);
我们完全可以在打完资源的时候,随机写入一段bytes数据到ab包的前面,然后记录写入的长度,也就是offset。在加载时,将offset作为参数就可以实现加载。(这里有一个风险,如果ab包的有效数据是以固定格式开头,那么还是容易被破解,未测试)。下图展示了一个随机写入22个byte之后,AssetbundBrower和AssetStudio看到的情况
下图展示,从带有22个byte的ab包中加载的结果
总结
LoadFromFile(string path, uint crc, ulong offset)
这种带offset的打包/加载方法的最大好处是没有内存的消耗,也没有加载上性能的损失,可以视作没有更改引擎代码或者hook引擎的情况下最好的方法。
简单,高效,易用。
Simlpe is Good !!!!!