JavaScript 强混淆
我的网站是纯内存缓存读 + js 渲染 spa,现在的瓶颈就是硬件配置低、带宽小,程序架构上可以说追求到极致了。其中,js 渲染是全站性能优化的关键一坏,服务器只负责吐出原始数据,而把路由解析、数据处理、布局渲染的计算压力都转嫁给了浏览器。
如此重要的前端部分我当然花了很大的心思。js 是明文的,只能做混淆。但是如果混淆得足够好,逆向成本过高,也是可以达到很好的代码保护。网上有很多 js 代码混淆的方法可以参考,但有些会让文件大小增加好几倍。这里我分享一下自己 js 强混淆的思路。
我实现 js 强混淆的关键一点就是字面量表达式。
原生写法:
str.trim();
字面量表达式:
str['trim']();
有了这个基础,混淆要做的就是进一步隐藏字符串了。我用了 ASCII 转码和 base64,使得字符基础变量简化为 64 个 base64 编码字符,以及特殊的空格和换行符。
以“我”字为例,base64 编码是“5oiR”。而“5oiR”对应的 ASCII 分别是 53、111、105、82。具体实现:
原生写法:
let str = '我';
混淆写法:
const
chr = code => String.fromCharCode(code),
base64_decode = str => decodeURIComponent(escape(atob(str))),
CHAR_5 = chr(53),
CHAR_o = chr(111),
CHAR_i = chr(105),
CHAR_R = chr(82);
let str = base64_decode(CHAR_5 + CHAR_o + CHAR_i + CHAR_R);
压缩后:
const e=e=>String.fromCharCode(e);var t;t=e(53)+e(111)+e(105)+e(82),decodeURIComponent(escape(atob(t)));
经过这样的强混淆后,整个 js 代码看不到显式的字符,包括类名、方法名、字符串变量等全部混淆了。这样的代码逆向会很耗时间;即便有耐心做了逆向,然后另一道保护就是,我服务端和前端的交互数据也是加密的,那是另一个故事了。