Javascript代码混淆综合解决方案-Javascript在线混淆器

文章来源:javascriptOnlineObfuscator">http://www.BizStruct.cn/JavascriptOnlineObfuscator

Javascript 代码混淆的目的

Javascript 是一种解释执行的脚本语言,主要应用于 Web 领域的客户端的浏览器中;由于 Javascript 解释执行的特性,代码必须明文下载到客户端,并且可以很容易的进行调试,使得 Javascript 代码的保护非常困难;

不同的人对 Javascript 代码的保护有不同的看法;有的人辛苦努力的代码,却可以被竞争对手轻易获得,他们就非常希望能有保护 Javascript 代码的方案,但现有的方案可能无法满足他们的要求;很多人认为 Javascript 语言很简单,Javascript 代码没有保护的价值,可能是他们的代码确实简单,或者他们并不了解 Javascript 语言强大的功能;还有的人认为现在都开源了,还保护代码干什么,当然开源的人是值得敬佩的,但对别人的代码的开源要求,却不是合理的。

为了提高用户的体验,出现了 Web 2.0 技术,并随着 AJAX 和富界面技术的发展,Javascript 在 Web 应用上的重要性越来越高,Javascript 代码的复杂性、功能和技术含量也越来越高,对Javascript 代码保护的需要也越来越迫切。

Javascript 在线混淆器的目的是为 Javascript 代码保护的需求,提供一种全新的综合解决方案,包括编码规则和免费的在线混淆器。

混淆和加密的区别

很多人将这两者混在一起讨论,实际上两者的目的有一定的区别,采取的手段也有很大的不同。加密主要是为了防止未经授权的使用,对这种情况即使破解了加密,也只能非法使用,并不一定能获得软件的代码逻辑;但对于脚本来说,防止对代码进行访问的措施,也属于加密,对这种情况,破解了加密,就获得了代码;而混淆是在无法阻止他人获取代码的情况下,采取的保护代码的逻辑不被他人理解的措施;对于混淆的代码,他人很难理解,无法进行修改和重新应用;
对于生成机器码的语言,比如 C 语言,只需要考虑未经授权的访问,几乎不需考虑代码的保护;因为对编译后的软件,只能反汇编为汇编语言代码,几乎无法分析出代码的逻辑。
对于生成中间代码的语言,比如 Java 和 C#,即需要考虑未经授权的访问,又需考虑代码的保护;;因为对编译后的软件,可以很容易的反编译为较高级的语言,从而了解到代码中的逻辑,并较容易的破解加密。而混淆后,即难于理解代码的逻辑,也不易找到加密点所在。
对于脚本语言,比如 Javascript,只能混淆,难以加密;因为脚本都是明文存在的,很容易调试的,通过跟踪可以较容易的破解上面两种目的的加密。但是混淆后的代码是难于理解代码的逻辑的。

我们只涉及到对 Javascript 脚本进行混淆,而不涉及加密;对于涉及到 Javascript 的系统的加密,我们建议不要将加密点放在 Javascript 脚本内,而是放在服务端的编译程序内,因为编译程序的加密可以采用更多的保护方式,加密的强度也更高。

我们首先要分析 Javascript 语言和混淆相关的特点,和现有的混淆产品的不足,然后再提出我们对 Javascript 代码混淆的解决方案,最后是我们的 Javascript 在线混淆器。

Javascript 语言和混淆相关的特性

Javascript 是一种解释执行的脚本语言,相对编译类型的语言有很多自身的特性,而其中一些特性会对代码混淆带来很大的困难。

无法定义类的属性和方法的名称是否需要被混淆

Javascript 是一种基于原型的语言,没有严格的类型定义。在自定义的类中,对于需要外部访问的属性和方法,不能进行混淆;对于内部访问的属性和方法,需要进行混淆;但Javascript 语言本身,无法对属性和方法进行这样的区分。为此我们要寻找一种变通的机制来识别属性和方法的名称是否需要混淆。

存在大量的系统定义的核心的和客户端的方法和属性不能被混淆

Javascript 语言本身定义了大量的核心的类、方法和属性;浏览器中也定义了大量的客户端的类、方法和属性;这些类、方法和属性都不能够被混淆,然而这些类、方法和属性的数量太大,无法通过枚举来避免混淆;为此我们需要寻找一种方法来标识这些类、属性和方法。

无法定义全局变量是否需要被混淆

全局变量是 window 对象的属性,局部变量是函数对象的属性;所有的局部变量都是可以和应该被混淆的,而全局变量有的需要混淆,有的不能混淆;但全局变量和局部变量的表现形式是一样的,难以区分;而且全局变量本身更无法定义是否需要被混淆。为此我们要找到一种方法来区分不能混淆的全局变量,和需要混淆的全局变量及局部变量。

Javascript 语言的这些特点,都对代码的混淆带来了很大的困难,如果不解决这几个问题,Javascript 代码的混淆就缺少实用的价值。

现有 Javascript 混淆产品的问题

当我们需要混淆 Javascipt 代码的时候,首先考察了市面上现有的产品,和一些论坛里对混淆的思路,但这些产品和思路都不能满足我们的要求。

有一个商品化的 Javascript 混淆产品,采用了和一种 C# 混淆工具相似的混淆方式,分析了代码里所有的标识符,对一些系统预设的标识符不混淆,对其他的进行混淆,同时提供用户对标识符的混淆进行选择和配置;这个产品的功能很多很复杂,但有一个很大的问题,就是预设的标识符有限,对于代码中用到的大量的系统定义的属性和方法,会进行混淆,为此需要自己手工配置,避免对这些属性和方法的混淆,这对于大型的系统几乎是一个不可能完成的任务。

有一些论坛里也讨论到混淆的思路,包括一些示例,这些思路更多的是改变标识符的表现形式,有的是用编码字符串的关联数组替换属性,比如将 xx.dd 替换为 xx["\x64\x64"];更复杂的是把 "\x64\x64" 之类保存到字符串数组,然后调用字符串数组作为关联数组的下标;这种思路可以避免上面的问题,但有一个更大的问题,就是混淆是可逆的,被混淆的标识符仅仅是被转换成了16进制的形式,可以很容易的恢复。

正是现有产品的不足,促使我们不得不研究自己的解决方案。我们的解决方案也是经过了几个版本,一开始的版本要复杂的多,花费了很大的工作量,但结果并不理想;几经修改才找到现有的解决方案;虽然开始的大量工作,最后几乎都废弃了,但没有前面的工作,也就没有后面的结果;所以即使您可能会认为我们的方案简单,那也只是我们努力的结果,而不是过程;而且简单的东西,往往是有效的。

Javascript 代码混淆综合解决方案

通过前面对 Javascript 的特性和相关混淆产品的分析,使我们认识到如果仅仅是在混淆器上下功夫是不够的;因为 Javascript 语言本身对混淆的功能有很大的限制,无法解决。为此我们设计了一个综合的解决方案,就是 Javascript 在线混淆器规则,只要是按照规则编写的 Javascipt 代码,都能使用 Javascript 在线混淆器混淆进行混淆。

Javascript 在线混淆器的规则并不复杂,但能够解决 Javascript 语言本身的特性和其他混淆产品遇到的问题。

规则一、所有用 window 约束的类、变量和函数都不混淆,其他的类、变量和函数都混淆。

全局的类、变量和函数本身都是 window 的属性,用不用 window 约束,从逻辑的角度是一样的。但我们可以借用 window 的约束来区分对全局的类、变量和函数是否需要进行混淆。

用 window 的约束必须是前后一致的,不但包括类、变量和函数的定义,也包括类、变量和函数的调用。

局部的类、变量和函数,因为没有 window 约束,所以都是混淆的。






























类型 混淆 不混淆
类定义 function Class1(){...} window.Class1 = function(){...}
函数定义 function Method1(){...} window.Method1 = function(){...}
变量定义 var Param1 = 1; window.Param1 = 1;
生成类的实例 var object1 = new Class1(); var object1 = new window.Class1();
函数调用 Method1(); window.Method1()
变量引用 var newParam = Param1; var newParam = window.Param1;

规则二、所有以小写字符开头的属性和方法都不混淆,以其他字母开头的属性和方法都混淆,用 window 约束的属性和方法应用规则一。

JavaScript 核心和客户端中有大量的系统定义的方法和属性不能被混淆,而这些方法和属性绝大多数都是以小写字母开始的,本规则保证了系统定义的方法和属性不被混淆。在 Javascript 客户端中仅有极少数的系统定义的以大写字符起始的方法和属性,对于这种情况,可以采用关联数组的方式避免被混淆,比如 object1["Method1"]();此方法也适用于第三方控件中可能会有的以大写字符起始的方法和属性的情况。

此规则也使我们可以在自定义的类中标识方法和属性是否被混淆,对于需要外部调用不能混淆的方法和属性,采用小写字母起始,对于内部的方法和属性,采用其他字母起始。






























类型 混淆 不混淆
类方法定义 Class1.Method1 = function(){...} Class1.method1 = function(){...}
Class1["Method1"] = function(){...}
对象方法定义 Class1.prototype.Method1 = function(){...} Class1.prototype.method1 = function(){...}
Class1.prototype["Method1"] = function(){...}
类属性定义 Class1.Prop1 = 1; Class1.prop1 = 1;
Class1["Prop1"] = 1;
对象属性定义 object1.Prop1 = 1; object1.prop1 = 1;
object1["Prop1"] = 1;
类方法调用 Class1.Method1(); Class1.method1 ();
Class1["Method1"]();
对象方法调用 object1.Method1(); object1.method1 ();
object1["Method1"]();

Javascript 在线混淆器的核心规则就是以上两点,另外还有几点说明。

标识符的混淆采用 Hash 算法,不可逆

Hash 算法是不可逆的,所以不能根据混淆后的标识符,来直接推出混淆前的标识符;但 Hash 算法依赖于 .Net 系统的实现,大多数的时候,.Net 的 Hash 算法是不变的,就是同一个标识符的混淆结果是一样的;如果能够枚举足够多的标识符,仍然可能根据相同的混淆结果,知道混淆前的标识符。

如何调用混淆后的类、方法和属性

对于混淆代码的内部调用,只要采用相同的规则,要么都混淆,要么都不混淆,就能正确的调用。

对于混淆代码的外部调用,可以有两种方式,一种是不混淆,代码内部采用不混淆的规则,外部采用不混淆的可理解的标识符调用;另一种是混淆,代码内部采用混淆的规则,外部也采用混淆后的不可理解的标识符调用,但此方式依赖于 .Net Hash 算法的实现,在不同版本的 .Net 实现中的 Hash 算法有可能不同,以至混淆后的标识符不一致,从而导致重新混淆后,需要替换原来混淆的标识符。

为何有“清除空格,保留分号后的回车”的选项

Javascript 语法要求全局函数的结尾必须有分号或回车,如果遗漏了分号,而又清除了所有的回车,总是提示第一行缺少分号,无法定位错误所在;采用本选项可以有助于寻找缺少的分号的位置。

以下 Javascript 语言的保留字不混淆

break, case, catch, continue, debugger, default, delete, do, else, false, finally, for, function, if, in, instanceof, new, null, return, switch, this, throw, true, try, typeof, var, while, with

混淆器预定义了一些 window 的属性和方法

Javascript 核心类和函数是不能被混淆的,他们实质上都是 window 的属性和方法,按照规则应该用 window 约束,以避免被混淆;但对于 Object、Array、Date、ActiveXObject 等核心类,混淆器已经预定义不会混淆,不需要再用 window 约束。对于 alert 等 window 常用的方法和 document 等 window 常用的客户端属性,也有预定义。其他需要预定义的类和方法,我们会逐步添加;没有预定义的全局类和函数,如果不能混淆,必须用 window 约束。

以下全局的类、变量和方法不混淆

ActiveXObject, alert, Array, Boolean, Date , document, Math, Number, Object, RegExp, String, window

Javascript 在线混淆器

请访问 http://www.BizStruct.cn/JavascriptOnlineObfuscator/JavascriptOnlineObfuscator.aspx

(0)

相关推荐

  • Javascript代码混淆综合解决方案-Javascript在线混淆器

    文章来源:javascriptOnlineObfuscator">http://www.BizStruct.cn/JavascriptOnlineObfuscator Javascript 代码混淆的目的 Javascript 是一种解释执行的脚本语言,主要应用于 Web 领域的客户端的浏览器中:由于 Javascript 解释执行的特性,代码必须明文下载到客户端,并且可以很容易的进行调试,使得 Javascript 代码的保护非常困难: 不同的人对 Javascript 代码的保护有不同

  • 使用CoffeeScrip优美方式编写javascript代码

    JavaScript无疑是在web最伟大的发明之一,几乎一切网页动态效果都是基于它丰富的计算能力.而且它的能力在各种新的JavaScript的Engine下也越来越强了,比如Google Chrome用的V8 Engine. 但是由于诞生的太早,有很多语法定义在今天看来有些效率低下了,一些更加先进的语法形式,由于历史原因,没办法加入到现在的JavaScript语言中,可以说一种遗憾. 世界上的很多天才都在为构建更好的JavaScript而努力.已经有了很多尝试,其中最有前途的,无非就是Coffe

  • javascript 代码是如何被压缩的示例代码

    随着前端的发展,特别是 React , Vue 等构造单页应用的兴起,前端的能力得以很大提升,随之而来的是项目的复杂度越来越大. 此时的前端的静态资源也越来越庞大,而毫无疑问 javascript 资源已是前端的主体资源,对于压缩它的体积至为重要. 为什么说更小的体积很重要呢:更小的体积对于用户体验来说意味着更快的加载速度以及更好的用户体验,这也能早就企业更大的利润.另外,更小的体积对于服务器来说也意味更小的带宽以及更少的服务器费用. 前端构建编译代码时,可以使用 webpack 中的 opti

  • 分享10个优化代码的CSS和JavaScript工具

    检查和测试代码来发现任何潜在错误,从而在放到网站上之前及时消除错误是一个非常重要的过程.代码检查的过程也俗称为是Web设计师 和开发者之间的linting.作为一个设计师,如果你想要写出高度优化的代码,那么你一定需要linting工具.有两种类型的代码检查工具.一种是在 执行时间检查代码中的错误和bug.另一种是使用静态代码分析技术并在执行前检查码.后者因为可以节省时间和麻烦显然更佳. 事实上,linting可以放在不同的阶段.如果你喜欢在敲代码的时候测试代码,那么你可以使用lint工具.当然,

  • jquery下组织javascript代码(js函数化)

    从神奇的"$"函数开始 "$"函数将在文档加载完成之后为一个指定的button 绑定事件,这些代码在单个网页中工作正常.但是如果我们还有其它的网页,我们将不得不重复这个过程. 复制代码 代码如下: <a href="javascript:;" id="sayHello">Say Hello</a> <script type="text/javascript"> //whe

  • JavaScript 代码压缩工具小结

    UglifyJS UglifyJS是构建于nodeJS服务器端之上的一个代码压缩工具,目前jQuery使用它来压缩,压缩效果比较好. GitHub主页:http://github.com/mishoo/UglifyJS/ 在线使用:http://marijnhaverbeke.nl/uglifyjs 使用方法: 从http://nodejs.org下载nodejs,用到的是node.exe 再从UglifyJS的GitHub主页下载它的最新版本 复制node.exe到UglifyJS的bin目录

  • 把JavaScript代码改成ES6语法不完全指南(分享)

    目录 * 核心例子 * 修改成静态变量(const)或块级变量(let) * 开始修改 * 疑问解释(重复定义会发生什么) * 疑问解释(let的块级作用域是怎样的) * 疑问解释(const定义的变量在基础数据类型和引用类型中的差异) * 修改成Promise的形式 * 预备知识(回调函数是什么) * 预备知识(如何把回调函数改为Promise) * 开始修改 * 修改成箭头函数(Arrow Function) * 预备知识(箭头函数是什么) * 预备知识(箭头函数函数中的this是个坑) *

  • 【经验总结】编写JavaScript代码时应遵循的14条规律

    本文讲述了编写JavaScript代码时应遵循的14条规律.分享给大家供大家参考,具体如下: 1. 总是使用 'var' 在javascript中,变量不是全局范围的就是函数范围的,使用"var"关键词将是保持变量简洁明了的关键.当声明一个或者是全局或者是函数级(function-level)的变量,需总是前置"var"关键词,下面的例子将强调不这样做潜在的问题. 不使用 Var 造成的问题 var i=0; // This is good - creates a

  • javascript动态获取登录时间和在线时长

    本文实例介绍了javascript动态获取登录时间和在线时长的相应代码,分享给大家供大家参考,具体内容如下 效果图: 实现代码: <html> <head> <title>online</title> <script language=javaScript> ///这里是获得登录时候的时间,用来和动态的时间做差来求时长 var s = new Date(); function clockon() { var thistime = new Date

  • 浅谈JavaScript 代码整洁之道

    概述 一张幽默的图片:软件质量通过你在阅读代码的时候有多少报怨来进行评估 Robert C. Martin 在 <代码整洁之道> 中提到的软件工程原则,同样适用于 JavaScript.这不是一个风格参考.它指导如何用 JavaScript 编写可读.可复用.可重构的软件. 并不是每一个原则都必须严格遵循,甚至很少得到大家的认同.它们仅用于参考,不过要知道这些原则都是<代码整洁之道>的作者们累积多年的集体经验. 我们在软件工程方面的技术发展刚刚超过 50 年,我们仍然在学习很多东西

随机推荐