前端如何给 JavaScript 加密(不是混淆)?

2021-12-17 14:53发布

如果是从知识产权保护角度来看,脱离混淆的js加密是伪命题,无论怎么加密,如果不加以混淆手段保护,都没有意义。如同传统软件的加壳保护,js混淆给底层的加密算法加了最基本的保障,在js层面来说,混淆和加密一定是相辅相成的。

1、为什么需要js混淆

显而易见,是为了保护我们的前端代码逻辑。在web系统发展早期,js在web系统中承担的职责并不多,只是简单的提交表单,js文件非常简单,也不需要任何的保护。

随着js文件体积的增大,为了缩小js体积,加快http传输速度,开始出现了很多对js的压缩工具,比如 uglify、compressor、clouser。。。它们的工作主要是:合并多个js文件,去除js代码里面的空格和换行,压缩js里面的变量名,剔除掉注释

2、js混淆是不是纸老虎

这是一个老生常谈的问题。实际上,代码混淆早就不是一个新鲜的名词,在桌面软件时代,大多数的软件都会进行代码混淆、加壳等手段来保护自己的代码。Java和.NET都有对应的混淆器。黑客们对这个当然也不陌生,许多病毒程序为了反查杀,也会进行高度的混淆。只不过由于js是动态脚本语言,在http中传输的就是源代码,逆向起来要比打包编译后的软件简单很多,很多人因此觉得混淆是多此一举。

3、如何进行js混淆

js混淆器大致有两种: 通过正则替换实现的混淆器,通过语法树替换实现的混淆器

第一种实现成本低,但是效果也一般,适合对混淆要求不高的场景。第二种实现成本较高,但是更灵活,而且更安全,更适合对抗场景,我这里主要讲一下第二种。基于语法层面的混淆器其实类似于编译器,基本原理和编译器类似,我们先对编译器做一些基本的介绍。

名词解释

token: 词法单元,也有叫词法记号的,词法分析器的产物,文本流被分割后的最小单位。

AST: 抽象语法树,语法分析器的产物,是源代码的抽象语法结构的树状表现形式。

4、混淆对性能的影响

由于增加了废代码,改变了原有的AST,混淆对性能肯定会造成一定的影响,但是我们可以通过规则来控制影响的大小。减少循环混淆,循环太多会直接影响代码执行效率,避免过多的字符串拼接,因为字符串拼接在低版本IE下面会有性能问题,控制代码体积,在插入废代码时应该控制插入比例,文件过大会给网络请求和代码执行都带来压力

5、混淆的安全性

混淆的目的是保护代码,但是如果因为混淆影响了正常功能就舍本逐末了。由于混淆后的AST已经和原AST完全不同了,但是混淆后文件的和原文件执行结果必须一样,如何保证既兼顾了混淆强度,又不破坏代码执行呢?高覆盖的测试必不可少:对自己的混淆器写详尽的单元测试,对混淆的目标代码做高覆盖的功能测试,保证混淆前后代码执行结果完全一样

多样本测试,可以混淆单元测试已经完备了的类库,比如混淆 Jquery 、AngularJS 等,然后拿混淆后的代码去跑它们的单元测试,保证和混淆前执行结果完全一样