杜郎俊赏 - dujun.io

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 代码看不到显式的字符,包括类名、方法名、字符串变量等全部混淆了。这样的代码逆向会很耗时间;即便有耐心做了逆向,然后另一道保护就是,我服务端和前端的交互数据也是加密的,那是另一个故事了。

标签: 开发 前端
日期:2022-10-19