加密器加密(lua代码加密):

我框架中用的是tolua所以直接使用框架提供的luajit加密,可以参考,tolua也有样例代码比较方便。

内存数值加密:

遇到有次玩家使用葫芦侠等工具,恶意修改客户端内存中的值,向服务器发送溢出值(无符号数改为有符号-1即可溢出),刚好服务器又未对这个数值做校验,最终导致数据库数据溢出21亿。

这种情况客户端可以做一些规避策略。

主要思路是,向内存存储值时进行加密,增加别人在内存中寻值的难度。常见的比如取反(UI上显示6换算到2进制是110,但是我们保存变量时取反,在内存存中存001),异或,或者一些其他随机算法。(Tips: 最终还是要服务器端来解决这个问题,客户端的策略只能扰乱数值,但是最终显示到UI的时候还会让玩家看到实际数值)

资源加密:

游戏资源一般比较较大,一般只选择对资源的部分字节进行加密,以节省运行时解密所需的性能消耗。
Unity资源加密一般指AssetBundle加密,为了让资源加密的同时又不影响AssetBundleAPI的加载,有两种处理方案。
方案一: 头部和其他任意位置加密部分字节,即在assetBundle文件的部分位置,使用加密算法进行打乱。读取时,因为要解密这些字节,需要使用LoadFromMemory+C#字节流的方法,进行读取操作。

该方法需要将Bundle先ReadAllBytes到内存中,解密后,再从内存中读取Bundle,此方案因为要ReadAllBytes,会造成短时间的极大的内存消耗,而且如果使用不是L2cpp版本(非L2cpp的GC无内存碎片整理,易造成回收内存分块),加载Bundle时申请连续大内存块,容易造成内存占用暴增。

不过该问题已经在Unity2018以后的版本有了解决方案,即Unity提供了流式加载LoadFromStream,不用一次加载所有文件在进行解密了。
方案二:效率更快,但是不太安全的头部加密。翻查AssetBundleAPI时发现,LoadFromFile方法其实提供了第三个参数offset,LoadFromFile(string path, uint crc, ulong offset),意为读取时跳过offset长度的字节。而跟LoadFromFile配合的LZ4类型压缩,最重要的就是头文件。

我们可以以此为思路,在文件头部进行加盐。然后使用offset跳过加盐的部分,以实现一种加密的效果。

这种方案可以在对性能要求较高,但是Unity版本较老旧的情况下使用。

不过坦诚的讲,这种方案只能简单的预防一些反编译工具。对有心之人无太大作用,因为最终的秘钥,只是一个ulong,太不保险。

常用加密算法:

加盐加密,栅栏加密,异或加密。都比较简单,百度都有比较详细的解释。

进阶加密算法:

非对称加密,这个一般用在网络消息传输中。
百度百科流程解释:
1.A要向B发送信息,A和B都要产生一对用于加密和解密的公钥和私钥。
2.A的私钥保密,A的公钥告诉B;B的私钥保密,B的公钥告诉A。
3.A要给B发送信息时,A用B的公钥加密信息,因为A知道B的公钥。
4.A将这个消息发给B(已经用B的公钥加密消息)。
5.B收到这个消息后,B用自己的私钥解密A的消息。其他所有收到这个报文的人都无法解密,因为只有B才有B的私钥。