打印

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

文章来源: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




混淆效果的展示,请访问 http://www.BizStruct.cn/JavascriptOnlineObfuscator/BizStruct.js.htm
本帖最近评分记录
  • bound0 威望 +5 原创内容 2006-9-23 09:05

因为主机有防盗链,所以图片显示不了,请直接访问

这个只是对标识符的替换,破坏了标识符原有的描述性,另外所用的替换标识看上去比较让人眼花而已,并没有对源代码的结构进行混淆。

只要写一段小程序,把所有被混淆的标识符再重新用其他看起来比较顺眼的标识符替换,代码就会变得易读得多了。至于标识符原有的描述性是无法简单恢复的,但对于写代码不遵守风格规约的人来说,他们的代码可能本来就缺乏标识符的描述性。而对于受过足够训练的脚本老手来说,读这种代码是可以忍受的,很快就可以理解代码关键部分的原理,从而写出类似的代码来。这样代码原作者保护自己创新工作的努力等于是失败了。

因为不可能对代码的结构进行混淆,所以说单用混淆,不用加密也是不可靠的。

此外质疑一下“标识符的混淆采用 Hash 算法,不可逆”这段,有点“庸人自扰”的感觉(不是说这位作者不好,可能考虑的东西一多,头脑就有暂时点发木了,人皆如此,没有例外)。产生替换标识符的办法有的是,奈何要受限于“Hash 算法依赖于 .Net 系统的实现”什么的。

无论如何,做这种研究是很有意义的。

在本论坛上,早就更深入的讨论过这个问题了(像这样的混淆也早就被规了类)http://bbs.blueidea.com/viewthread.php?tid=2440360 ,可惜这位作者没有关注到我们的讨论。看来蓝色的影响因子还不够啊……我等需继续努力!
[Bound0 专题列表]QUE SAIS-JE?
生物信息技术支持动漫论坛动漫分享群:45274013

回复要回复到点子上

看过所谓的深入讨论了,不过我实在没有发现对我有什么帮助,里面罗列的东西是多,可发帖者把自己认为有价值的和没价值的都混杂在一起;不知道有没有人根据这个帖子,作出了什么有价值的工作;或者是发现 javascript 的混淆没有意义,从而避免了无价值的工作;如果想要体现价值的话,就把你认为有价值的东西整理出来,我们来看看是不是真的有价值。不知道为什么,在那个帖子里,我仅仅回复了一个链接 www.BizStruct.cn/JavascriptOnlineObfuscator,可被斑竹删了,如果就是这个气量的话,那把这个帖子也删了,我没有意见。

混淆也就是标识符的混淆和流程的混淆;流程的混淆即使不是不可能的,也是极其困难的,至少还没有看到这方面的成果;剩下的就只有标识符的混淆;可按照楼上的第一个观点,标识符的混淆是没有意义的,否则说那么多标识符混淆没有作用干什么。你就干脆的说,标识符混淆没有作用,看看有多少人认同你。

批驳以前,先搞清楚“Hash 算法依赖于 .Net 系统的实现”是什么意思再说;有的混淆用a, b, c之类的标识符进行替换,可他们考虑到外部调用没有,这次混淆的结果是a,下次混淆的结果是b,没法外部调用;Hash 算法这次是 abc,下次还是 abc,外部可以用混淆后的结果调用;可能存在的问题就是不同的 .net 版本的hash算法可能不同。不过没有兴趣自己做一个 Hash 算法。

我们认为自己的综合解决方案解决了 Javascript 代码混淆的三个问题。
1、保证了系统定义的核心的和客户端的方法和属性不被混淆。
2、让 Javascript 可以定义类的属性和方法是否需要被混淆。
3、让 Javascript 可以定义全局的类、变量和函数是否需要被混淆。

很可惜,你批驳的几点都不是我们专属,大家都是这么做的。

TOP

还在为头像烦恼?还在为不能关注好友动态烦忧?快来蓝色理想家园吧!

好吧,我试着点对点的回复一次

引用:
原帖由 newwalter 于 2006-9-15 11:46 发表
我们认为自己的综合解决方案解决了 Javascript 代码混淆的三个问题。
1、保证了系统定义的核心的和客户端的方法和属性不被混淆。
2、让 Javascript 可以定义类的属性和方法是否需要被混淆。
3、让 Javascript 可以定义全局的类、变量和函数是否需要被混淆。
这些的意义我都理解,且尊重价值,所以才说“做这种研究是很有意义的”。本来就打算加分的,因为没有具体核实发帖人是否就是作者,所以暂时搁置了。从你回帖的口气来看,你是作者吧?是的话请说明一下,可以加分哦。(加分是对价值的认可,不具有其他的倾向性)
引用:
原帖由 newwalter 于 2006-9-15 11:46 发表
批驳以前,先搞清楚“Hash 算法依赖于 .Net 系统的实现”是什么意思再说;有的混淆用a, b, c之类的标识符进行替换,可他们考虑到外部调用没有,这次混淆的结果是a,下次混淆的结果是b,没法外部调用;Hash 算法这次是 abc,下次还是 abc,外部可以用混淆后的结果调用;可能存在的问题就是不同的 .net 版本的hash算法可能不同。不过没有兴趣自己做一个 Hash 算法。
外部调用的问题可以通过更精细的统筹策略来解决,比如可以把某次使用的标识符保存起来,下次接着用,还可以在适当的地方给同一标识符提供多个别名……等等。犯不着为了莫须有的外部调用而全面应用 Hash 算法。我只是提出质疑,不是“批驳”。
引用:
原帖由 newwalter 于 2006-9-15 11:46 发表
不知道为什么,在那个帖子里,我仅仅回复了一个链接 www.BizStruct.cn/JavascriptOnlineObfuscator,可被斑竹删了,如果就是这个气量的话,那把这个帖子也删了,我没有意见。
那个帖子是我本人亲自删的,这和“气量”什么的很难扯上关系吧?删与不删,于我何加?那个帖子的确如你所言,仅仅是一个链接,如果早发几个月我会把它视为讨论资源留起来,但那个帖子沉下去已不是一天两天了,你的链接被别人当成变相广告理解也很自然吧。既然已经开了新的主题,还在那个老主题里留个尾巴干嘛用呢?而且不论你是否认同,那个主题的确是被更深入(至少是更丰富)地讨论了,而你回的那贴会把讨论导向更初级的阶段。
引用:
原帖由 newwalter 于 2006-9-15 11:46 发表
混淆也就是标识符的混淆和流程的混淆;流程的混淆即使不是不可能的,也是极其困难的,至少还没有看到这方面的成果;剩下的就只有标识符的混淆;可按照楼上的第一个观点,标识符的混淆是没有意义的,否则说那么多标识符混淆没有作用干什么。你就干脆的说,标识符混淆没有作用,看看有多少人认同你。
我什么时候说过“标识符的混淆是没有意义的”了?我说的是“单用混淆,不用加密也是不可靠的”。随便把别人说的话演绎成极端观点可不好玩。我觉得,凡是有兴趣研究“混淆|加密”的人都应该是一派才对,如果我们再窝里反的话,就更没有前途了。本来对“混淆|加密”持反对意见或是认为“混淆|加密”没有意义也不可能成功实现的人就占了大多数。所以希望楼主能往积极的方向去理解我的话。
引用:
原帖由 newwalter 于 2006-9-15 11:46 发表
看过所谓的深入讨论了,不过我实在没有发现对我有什么帮助,里面罗列的东西是多,可发帖者把自己认为有价值的和没价值的都混杂在一起;不知道有没有人根据这个帖子,作出了什么有价值的工作;或者是发现 javascript 的混淆没有意义,从而避免了无价值的工作;如果想要体现价值的话,就把你认为有价值的东西整理出来,我们来看看是不是真的有价值。
我是把材料视为资源来罗列的:首先要有所见识,然后才能有所判断。否则判断便是盲目的。在脚本的“混淆|加密”这方面,我们还远未达到可以直接给出自己的判断的“自由王国”的境地,所以最好是先老老实实地收集资源。我所罗列的东西对想要做出“有价值的和没价值”这种判断的人而言是“有价值的”。能够这样我已经知足了,至于还要怎样进一步地“体现价值”,我还在探索中。楼主的工作,也加速了包括我在内的同道人的探索。但是据楼主说没有从我们的讨论中得到什么帮助,那也就是说在这种广义的交流中我遗憾地成为单方面受益者了……遗憾~~~~
引用:
原帖由 newwalter 于 2006-9-15 11:46 发表
很可惜,你批驳的几点都不是我们专属,大家都是这么做的。
没有“批驳”什么(你也没有立什么论点吧,我批你什么),好像也归纳不出“几点”来?也并非针对你的做法,只是说了普遍性的事实。不解,楼主何来的火药味?


让我们都把眼睛往前看,把注意力着眼于发展吧!我相信,脚本的“混淆|加密”会成功实现的。
[Bound0 专题列表]QUE SAIS-JE?
生物信息技术支持动漫论坛动漫分享群:45274013

TOP

其实我的帖子里把解决方案已经说得很详细了,甚至于自己都觉得有点罗嗦,主要是省得有人看不明白时,回复起来也麻烦。结果现在还是不得不在这罗嗦。

我们的观点在帖子里很明确,就是 javascript 代码只能混淆,难以加密。

“对于脚本语言,比如 Javascript,只能混淆,难以加密;因为脚本都是明文存在的,很容易调试的,通过跟踪可以较容易的破解上面两种目的的加密。但是混淆后的代码是难于理解代码的逻辑的。”,

你的回复里有一半是是说的混淆的缺点,所以我把上面的回复换一个说法,“你是不是认为标识符的混淆是没有意义的,否则说那么多标识符混淆没有作用干什么?”。如果一件事你必须去做,而你又不断降低他的价值,这样有意义吗?

你的回复里有三分之一说不赞成采用 Hash 算法。不知道你用混淆工具用的多不多,我有大概7,8个项目,都应用了 Xenocode,Xenocode 也是应用的 Hash 算法,不过是专有的,更复杂。我把所有的混淆配置都放在了工程项目里,而不是 Xenocode 项目;在 Xenocode 项目里几乎是空的,没有定义任何标识符。如果在 Xenocode 项目里定义了任何标识符,就必须在两个项目里维护。同样,按照你的方法 “比如可以把某次使用的标识符保存起来,下次接着用,”,那你也必须在两个地方维护表示符。我们的观点是几乎没有必要手动设置标识符的混淆。

对于,“犯不着为了莫须有的外部调用而全面应用 Hash 算法”,来说,外部调用不是莫须有的,Javascript 语言是区分不出局部变量或全局变量的,所以只要有一个外部调用,就必须用统一的混淆方法。

我就不感谢你用了六分之一的篇幅来说我们的产品,“做这种研究是很有意义的”,而没说是有价值的。

这个论坛是我在 Google 上找到的那个所谓的深入讨论的帖子发现的,如果其他人也找到了这个帖子,就看不到我们被删除的回复了。我想对很多人来说,我们的帖子价值可能更大,至少他们能明白、验证和应用我们的产品。

帖子的内容是不能乱删的,特别是当你认识 到内容的价值的时候,至于你说的 “而你回的那贴会把讨论导向更初级的阶段”,在我们看来有些可笑。虽然说出来可能不一定恰当,但产品的价值要比帖子的价值要更高。

我们对Javascript 的混淆花费了很大的精力,走了太多的弯路,现在的产品实际上只占十分之一的工作量,其他的全都废弃了,最终我们实现了自己的目标,对一百多k,上万行的 Javascript 代码实现了保护。但很多人并没有深入的研究,而只是在论坛里说说而已。

我们的产品和我们的文章都是花费了很大努力,自信会对别人有价值,可我们希望对他的回复同样要有价值。

[ 本帖最后由 newwalter 于 2006-9-18 10:39 编辑 ]

TOP

有些研究是历史性的,无法跳过,必须得做,而且早晚总会有人去做。但是你不能因此就夸大了你现阶段的成果。你可以回头看一下三楼的回复,不存在你说的“不断降低价值”的问题。你敢说仅仅混淆了标识符的方案就是可靠的吗?

对于外部调用,“Javascript 语言是区分不出局部变量或全局变量的”,所以应该对变量名有所统筹,而不是“必须用统一的混淆方法”,更不必“全面应用 Hash 算法”。“必须”这样的讲法本来就太绝对了,不是慎思谨言的风格。

混淆器有混淆器的评价标准,对此我不敢妄言,只是你们目前的产品还没有成熟到可以飞跃到一个新的历史阶段的境界,比起现有的(某些免费的)混淆器来,你们的混淆器的优点就在于你在4楼最后总结的三点。仅凭这些优势还不足以把最终产品的价值看得太重,甚至比技术发展还重要(楼主言:“产品的价值要比帖子的价值要更高”)。如果非要尖锐地说,这种价值判断才是“可笑”的。

“一百多k,上万行的 Javascript 代码”本来就不易读懂,这个时候要是再混淆一下就可以说是在一定程度上实现了保护。但是,混淆后的代码的可读性和未混淆的原始代码的可读性成正比,这一点即使不做任何说明,大家都也是明白的。

做过深入研究是好的,而且最好是能坚持做下去。据我所知,本论坛上有好几位朋友都在坚持研究“混淆|加密”问题。我们偶尔会在论坛上说说,交流一下彼此最新的成果。
引用:
原帖由 newwalter 于 2006-9-17 22:06 发表

我们的观点在帖子里很明确,就是 javascript 代码只能混淆,难以加密。

“对于脚本语言,比如 Javascript,只能混淆,难以加密;因为脚本都是明文存在的,很容易调试的,通过跟踪可以较容易的破解上面两种目的的加密。但是混淆后的代码是难于理解代码的逻辑的。”,
我们的观点也很明确:混淆和加密要结合使用,单用哪一个都是不可靠的。而且我还认为“混淆后的代码是难于理解代码的逻辑的”这种说法是不可靠的,因为楼主自己也曾说过“流程的混淆即使不是不可能的,也是极其困难的”,既然寓于流程中的逻辑没有被混淆,为何还不避讳“逻辑”一词。

楼主一直在提“价值”这个词,不知怎样的回复才是楼主认为有“价值”的,或许像“好,这个不错,强哦,我顶……”这样的回复才是楼主需要的。

我们欢迎大家来推广新产品、新技术,这正是所谓“当仁不让”。但是在过去的讨论主题后面加链接广告的做法还是要受一些限制的,因为如果只要“推广新产品、新技术”就可以这么做的话,相信有意为之者不只一家两家而已,讨论秩序很快就会被破坏。对此,望能理解。

不妨再回顾一下3楼的帖子。真理是可以越辩越明的。
[Bound0 专题列表]QUE SAIS-JE?
生物信息技术支持动漫论坛动漫分享群:45274013

TOP

不要以为你喜欢什么样的回复,别人就喜欢什么样的回复;

如果有人赞同我,我当然高兴;有人有问题,我会解答;如果有人质疑,我也可以解释;我就受不了有的人,作出一付很了解的样子,品头论足。

就你第一个回复里的两点都是站不住脚的;混淆是必选的,没有讨论的余地;Hash 算法也是优先的。

你现在有可行的方案吗?你有这时间还不如整理出一个方案,整天说加密加密,等你想好方案再说。做不到的话,再说也没有。

我是干事的人,都是干完事以后再说,在评价别人以前,先看看自己能做什么,做了什么。

就是现成的,产品化的东西,你能找到几个可用的吗。

自己怎么想的就怎么说,不要一开始还引用别人的话说我在做广告,现在才说出是自己的想法;我把自己的解决方案开放给大家,免费的产品推荐给大家用,难道这样也有要受到限制吗?那个帖子的目的是什么,不就是讨论技术吗,现在有价值的内容被删除了,用规则作借口;所谓的规则,就像中国的法律,是一种统治的工具,论坛也不例外。

不要开口闭口真理,知道吗,整天说廉洁的人最腐败。

TOP

我对混淆没研究,就不参与你们俩的论战了,不过如果我之前有看到你发的那个超链接,我也是会删除的,因为在论坛里只发超链接,一般会认为是广告,如果你认为你的超链接有实际价值,最好是加以说明,谢谢。
子叶:子乌的叶子
帅哥们,美女们,新的一年终于来了,祝贺你们...终于又老了一岁~

TOP

LZ的解决方案是不是用来解决这个问题的:
在JS客户端脚本被混淆后,服务器端动态语言调用JS方法时,要么是JS脚本混淆时就保留一个混淆前后方法命名的列表嗲用的时候程序员去查自己想调用的方法编成什么了;要么就是LZ这样的方法,用Hash算法来省略掉查找明文保存的对照表的麻烦?


木有说明白。。应该是网站什么地写出来的时候动态脚本语言调用JS的方法时都是用的明文方法名,在网站调试完成以后把JS脚本混淆,然后再在动态语言里把所有的JS方法也都用Hash算法计算得到混淆后的值,,而不必去查混淆对照表?

不晓得说明白木有。。。。



至于两位争了半天的东西,我觉得没有多大意思,所谓的混淆同样是一种加密算法(不同意的可以去看一下密码学导引中提到的“秘本加密”),而对于JS来说,既然用和已经拿到了明文,名称的改变最多只会造成阅读的不方便而已,对于想看到的人来说,混淆又算什么

LZ所说的观点都是在自己的一套动态脚本调用JS解决方案前提上的;而斑竹室在混淆算法上的,混淆方法有很多,而Hash算法能保证不去保留和查找一个混淆明文对照表,,,两者是在没有多大争论的价值

[ 本帖最后由 ariex 于 2006-9-19 12:03 编辑 ]

TOP

我们的应用是这样的,有多个 js 文件,只有会在这些 js 文件外调用的类、函数、属性和方法,采用不混淆的标识符规则,其他所有的都采用混淆的标识符规则,那么外部就采用原文进行调用。

至于 Hash 算法则是为了想要对外部调用进行混淆,每次混淆的结果都是一样的,外部采用混淆后的标识符进行调用。

这个争论确实没有意义,如果在其他的帖子,我们是不会回复的;这里,我们是为了说明我们解决方案。

之所以区分混淆和加密,是因为两者所采用的技术有很大的区别,两者的目的也有一定的区别,如果混在一起讨论,就说不清了。

TOP

嗯,先说明下:ariex说的“加密”一词是广义的加密,我和newwalter在以上说的是在脚本“混淆|加密”这方面有所特指的“加密”,是把脚本代码以经过某种“加密处理”的字符串形式保存起来,经还原之后再执行的一类保护代码的措施。除“加密”之外其它的措施,基本上都可以归为“混淆”一类。


我可不认为这算是什么“论战”,只是为了把事实说明白了而已。我说“真理是可以越辩越明的”也就只是这个意思。


是这样的,因为楼主自己曾说
引用:
Hash 算法依赖于 .Net 系统的实现,大多数的时候,.Net 的 Hash 算法是不变的,就是同一个标识符的混淆结果是一样的;如果能够枚举足够多的标识符,仍然可能根据相同的混淆结果,知道混淆前的标识符。
所以我想,既然Hash有这样的局限性,为什么还要局限于Hash算法呢?这不是有点“庸人自扰”的味道吗?

而且不仅如此,像楼主那样单纯地应用Hash算法,还有一些问题是解决不了的,比如当你的脚本需要和一个外源的脚本互作,引用这个外源的脚本中的变量时,因为不能对外源的脚本(不在你的管辖范围内)也应用Hash算法,这些变量名被替换后就会找不到相应的变量了。所以说,应该对变量名进行统筹规划,而不是简单地统一应用某种算法。一个好的混淆器,应该对代码的改变形成日志,以根据日志来应付处理可能存在的意外情况。

是否用Hash算法的问题只不过是一个实现上的细节问题,本来就没什么大不了的?我在3楼只是用了两行话,表示一下“质疑”而已。真正重点的问题,楼主在以上的回贴中却全都没有正面的回应,这可谓是避重就轻了。楼主没有正面回应,而是一直试图将我的意思模糊化、偏歧化:楼主说“混淆是必选的,没有讨论的余地”——我什么时候和你讨论过“混淆是否必选”的问题了?我说的是,单用混淆是不可靠的(关于这一点,ariex的表述更直接:“混淆又算什么”)。如果你要否认这一点的话,应该去论证“单用混淆也是可靠的”才对,而不要顾左右而言他。

为了清楚起见,在这里集中回顾一下:
引用:
这个只是对标识符的替换,破坏了标识符原有的描述性,另外所用的替换标识看上去比较让人眼花而已,并没有对源代码的结构进行混淆。

只要写一段小程序,把所有被混淆的标识符再重新用其他看起来比较顺眼的标识符替换,代码就会变得易读得多了。至于标识符原有的描述性是无法简单恢复的,但对于写代码不遵守风格规约的人来说,他们的代码可能本来就缺乏标识符的描述性。而对于受过足够训练的脚本老手来说,读这种代码是可以忍受的,很快就可以理解代码关键部分的原理,从而写出类似的代码来。这样代码原作者保护自己创新工作的努力等于是失败了。

因为不可能对代码的结构进行混淆,所以说单用混淆,不用加密也是不可靠的。
引用:
“一百多k,上万行的 Javascript 代码”本来就不易读懂,这个时候要是再混淆一下就可以说是在一定程度上实现了保护。但是,混淆后的代码的可读性和未混淆的原始代码的可读性成正比,这一点即使不做任何说明,大家都也是明白的。
其实以上说的是常识性的东西,一般人(区别于楼主所讲的“有的人”)不需要“作出一付很了解的样子”就可以说了。

我删你链接的事情,Sheneyan的话已经可以说明白了吧?

“不要开口闭口真理,知道吗,整天说廉洁的人最腐败。”这句话的口气已经很不像是正常的讨论了,不过真的很抒情的说……我要为此赞扬一下楼主。
但是为什么提一句“真理”就不行了呢?仿冒楼主的句式来一句:不要开口闭口价值,知道吗,整天说财富的人最卑微。

敢情楼主只能接受好评啊?“干事儿的人”,不许别人说的。这个我没想到,冒犯了,不好意思呐!(我那样的回贴被认为是令人“受不了”的“品头论足”,我不知道楼主可以接受的是怎样的“质疑”,不妨试举一例。)我本来觉得楼主是“能干大事儿的人”,所以你才能总结出那些规律来,如果再多参考些资料,一定能做出很好的产品来呢。现在看来,我或许是“多情反被无情扰”罢了。如ariex所言,我一再回复着这个帖子,但是“觉得没有多大意思”了。

[ 本帖最后由 bound0 于 2006-9-19 20:02 编辑 ]
[Bound0 专题列表]QUE SAIS-JE?
生物信息技术支持动漫论坛动漫分享群:45274013

TOP

你到底对 Javascript 了解多少,连“外源的脚本”的问题都要拿来质疑,所有的 javascript 核心、客户端的调用和“外源的脚本”在语法上有区别吗?如果我们把这些问题都解决了,“外源的脚本”还存在问题吗?先别整天谈 Javascript 的混淆和加密,先把 Javascript 语言研究透了再说,否则根本是对牛弹琴。

知之为知之,不知为不知,我不想和你讨论加密的问题,因为我也不知道该怎么做;

有所为,有所不为,我也不想你讨论“单用混淆是不可靠的”的问题,因为我现在必须用混淆来保护自己的代码;不知道如果有人和你讨论“混淆和加密都是不可靠的“,你感不感兴趣,对我来说这两个问题都是浪费时间。

没想到你的价值就是指财富,这个我和你不太一样,我也理解了你为什么对我用那么多“价值”这个词有看法了。

我们认为的价值是其他人能用我们的产品保护他们的代码,是指应用价值。

最后我很质疑你到底有没有在实际的项目中用过某一种混淆器,否则你就不会认为 “应该对代码的改变形成日志,以根据日志来应付处理可能存在的意外情况” ,是一项轻松的工作。

TOP

"当你的脚本需要和一个外源的脚本互作,引用这个外源的脚本中的变量时,因为不能对外源的脚本(不在你的管辖范围内)也应用Hash算法,这些变量名被替换后就会找不到相应的变量了"

我不知道昨天这话说得是不是明白,但我说的这个问题确实是存在的。这里说的“外源的脚本”是和“自己的脚本”相区别而言的,或许也可以叫做“第三方的脚本”,反正就是你不能对其作任何改变的那些脚本。

我模仿你的句式造的那句话,本来也没什么深意,你推敲它干什么?”价值“这个词最普适的解释可能是:事物所具有的能让人们原意为之付出努力并能获得他人承认的性质。”财富“这个词的一种定义是:对社会全部产品和服务的子集的分配额度。(都是我自己随便诹的,别太当真)

现在你说话的主题渐渐地由讨论技术变成“质疑”我这个人了,不过一切技术的交流原本首先就是人之间的交流。通过交流,我终于渐渐理解你的感受了,可能你们现在就是想要专注于”混淆“,无论怎样总要有所尝试。我把我们的争执归结于”沟通不足“,3楼的回复是中肯而客观的,虽然对你们来说它可能会带来消极的影响。因为从1楼帖子的样式来看,似乎楼主只是转贴人(而不像是作者),所以我就没有考虑你的感受。如果我知道发贴人就是作者(而且你是在推广产品)的话,会给帖子加分,而且回复也会婉转得多。目前看来单用混淆的确是不可靠的(尤其是对于保护短小的代码和局部细节来说),但是楼主不要回避这个问题,这一论断将来也可能会被推翻,就看楼主和同道们的努力了(我本人也是混淆研究者中的一员)。

“对代码的改变形成日志,以根据日志来应付处理可能存在的意外情况”是一项保障措施(而且也可以做得比较”智能化“,当然得为此付出努力),如果是商业化的混淆器,还是应该提供这种特性的。
[Bound0 专题列表]QUE SAIS-JE?
生物信息技术支持动漫论坛动漫分享群:45274013

TOP

LZ的这个混淆根本就是垃圾,收废品的才觉得有价值
这也不能混,那也混不得,剩下能混的也只是换换变量名,顶个p用!
炮制了这种又臭又长的文章,显得很拽似的,上mop去骗骗小白还可以,这里是经典,再“忽悠”也没用。
熟红

TOP

第一个问题可能你还是没弄明白我们的两条规则,Javascript 核心、客户端的调用和“第三方的脚本”,从语法上看起来是没有任何区别的,既然我们解决了 Javascript 核心和客户端调用的混淆问题,“第三方的脚本”也就不是问题了(我们也跟着你重复)。所谓的Hash算法和这个是无关的,我根本就不混淆这些调用,为什么要和Hash算法有关系呢。

脚本的混淆会给代码的调试增加一定的工作量和难度,有的时候原文运行正常,可混淆后却有错误,调试起来又不如原文直观;运行的时候发现了错误,又不得不切换到原文进行测试,找出错误后,还要混淆后再验证一下。如果你不保证标识符每次混淆的结果是一样的,那你会被累死。我们做过大量的 .Net混淆和 Javascipt 混淆,这些都是经验;真理不是越辨越明,如果缺少实践的经验,是说不明白的。

采用了Hash算法,日志根本不是什么问题,其实这种情况下日志就已经没有存在的必要了,而是有更好的方法,你在我们的混淆器里输入一个标识符,然后混淆,结果就出来了,比查日志方便多了。

其实我们的根本分歧还是方法上的分歧,有的人是理论派,在做事前要把什么都搞明白,要不然不知道该怎么做;有的人是实践派,只要有一点想法就想去实现;不过在工程应用上光想是什么也得不出的,很多创新都是在实践中完成的;我们说过自己走过很多弯路,因为我们一开始的想法并不成熟,可反复尝试,也最终找到现在的方案;如果我们一开始就想混淆不是完善的,而不去作,就不会有任何结果。

至于你说的 “虽然对你们来说它可能会带来消极的影响”,实际上我们不在乎,有很多话叫“正确的废话”,反复说这样的话有意义吗?“单靠混淆保护是不可靠的” 这句话只有在你找到可用的加密方法以后才是有意义的,或者是你想得出“Javascript 代码是无法保护的“这样的结论时。

就你的第一个回帖的两个论点,一个我们认为是正确的废话,一个我们认为是由于你缺少混淆的实践应用经验;可你总认为自己中肯,我们也没办法。

[ 本帖最后由 newwalter 于 2006-9-21 09:15 编辑 ]

TOP

引用:
原帖由 piura 于 2006-9-21 08:40 发表
LZ的这个混淆根本就是垃圾,收废品的才觉得有价值
这也不能混,那也混不得,剩下能混的也只是换换变量名,顶个p用!
炮制了这种又臭又长的文章,显得很拽似的,上mop去骗骗小白还可以,这里是经典,再“忽悠”也 ...
如果你不需要混淆 Javascript 代码,我们的混淆器对你也没用。
如果你了解 Javascript 混淆的现状,你就不会说出这样的话。

[ 本帖最后由 newwalter 于 2006-9-21 11:28 编辑 ]

TOP

我明白你的规则,我描述的是这样的情况:“第三方的脚本”不能按照你说的规则进行规约(第三方脚本的内容由第三方控制,我们不能对其作任何改变),自己的脚本为了配合第三方脚本,其中某些变量必须和第三方脚本一致(所以也不能按照规则进行规约)。

我说的日志不光是用来查的,更重要的是用来恢复指定的变量名。日志主要是给混淆器自己用的,它也可以方便调试。混淆器做得好,就不会把人累死了。采用了日志以后,混淆算法可以更灵活多样,弥补单用一种算法的不足。

我并不像你想象那么缺乏实践;几番交流之后,我们已经知道对方的主旨是什么了。这就是“越辨越明”。

“单靠混淆保护是不可靠的” 这句“正确的废话”描述了一个公知的事实,不可无视这样的“废话”。这句话始终是成立的,直到有人找到一种“可靠”的混淆办法,在找到之前,向公众介绍你的工作时应该负责任地反复说明事实的现状。这样才有利于别人正确地理解和评价你的行为。

另一方面,“单靠加密保护也是不可靠的”——这些在你看来可以称作“理论”的观点原本都出自实践,出自真实的破解实践。理论是源于实践的,反过来又可以指导实践、加速实践,提高实践的水平。在缺乏理论指导的“拓荒阶段”,你可以从最基本的实践做起,但不可以就此自闭视野、坐井观天,试图闭门造车,而是应该广泛寻解,力求深入问题的本质。“理论派”与“实践派”的分歧之说,实质上是以“实践派”自居者以“务实”自誉,目中无人的轻狂说法。只有理论和只有实践的人,都不会取得成功的。

而且,实践者应该实事求是,真实、准确地认识自己的工作和成果。既不妄自菲薄,也不夜郎自大。任何事情要想做好,都需要从事者有一定的容量和造诣。



仅就混淆来说,除了替换变量名,还有很多事情可做:比如,引用置代(d=document,之后的document用d置代。引用置代不但可以混淆代码,还可以缩短代码的长度。)、插入讹码(在正常代码中间插入复杂而没有实际意义的代码)、别名复用(c=b=a=e=f=self,之后在某处又有b=top,一个变量有多个别名,而别名又常常被重新赋值给其它变量)、字面量运算化(把字面量变成某个语句或函数运算的结果)、字符编码……等等。


这里有一个引用置代混淆的例子。
http://bbs.blueidea.com/viewthread.php?tid=2378390

P.S.
你说你们以前还做过很多其它的尝试,我想这会是很宝贵的经验资料,能否开个主题谈一谈你们过去的探索经历,让同道一起分享你们的经验,让大家都少走些“弯路”。

[ 本帖最后由 bound0 于 2006-9-21 18:58 编辑 ]
[Bound0 专题列表]QUE SAIS-JE?
生物信息技术支持动漫论坛动漫分享群:45274013

TOP

引用:
原帖由 bound0 于 2006-9-21 18:57 发表
我明白你的规则,我描述的是这样的情况:“第三方的脚本”不能按照你说的规则进行规约(第三方脚本的内容由第三方控制,我们不能对其作任何改变),自己的脚本为了配合第三方脚本,其中某些变量必须和第三方脚本一 ...
你还是没有完全明白我们的规则和对混淆的回避方法,就以第三方脚本的几种可能情况而言。
1、如果调用第三方的全局的类、变量、函数
只要在调用的时候用 window 约束即可。
2、如果调用第三方的首字符以小写开始的方法和属性
直接调用即可
3、如果调用第三方的首字符以大写开始的方法和属性
要采用关联数组的方式,比如 object1["Property1"]。

采用以上方式和第三方脚本交互,第三方的脚本不需要作任何的变动,就能正确的调用。

如果在混淆代码出错的时候,用日志来反查出错的标识符也是有用的,不过还不如直接返回到源代码的情况进行调试,如果我们自己需要日志,肯定会想到做的。

Javascript 的语法太灵活,任何想要比标识符的混淆,更进一步的方案几乎都不可能是通用的。就你说的那几种混淆的方法,估计没人能做出来通用的,适合大系统的产品。


既然你感兴趣就说说我们一开始的方案。

当时的方案是两遍扫描,第一遍先把所有的函数定义和this的属性标识符都获得,也就是自定义的函数和属性,第二遍是把第一遍扫描获得的标识符中,所有以小写字符起始的标识符混淆,大写的字符起始的标识符不混淆;这是因为在我们的 C# 编程规范中,public 的方法和属性都大写,需要外部调用的就不混淆,private 的方法和属性都小写,必须混淆。

这个方案有两个问题,一是不能和系统定义的标识符同名,这样都会被混淆;二是只有自己定义的类可以用 this,像在事件里就不用 this,否则系统定义的属性会被混淆。

这两个问题解决一次是可以的,但太难避免了,一不小心新定义的方法就又可能和系统的方法重名,后来就发展到现在的方案。

[ 本帖最后由 newwalter 于 2006-9-22 10:11 编辑 ]

TOP

精彩,精彩,可惜我不懂,只是看了两人的对话,觉得都还不错,可以。就是这样争论才会有更大的启发,说不定你们可以讨论出来一个新东西哟。呵呵。加油!

TOP

嗯,的确是刚明白,开始文章看得不够仔细。你们的规则是完全的,已经穷尽了所有的可能。

这些研究很有意义(价值)。——加分了!

另外,我现在越来越讨厌自己在三楼说话的口气(当时没觉得),在这里郑重地道个歉!

我也一直在研究脚本代码保护,也有一段时间了(我比较倾向于混淆/加密结合的策略)。希望以后可以多交流。我会关注你们的进展。

虽然没能从数学上证明,但是从经验来看“引用置代、插入讹码、别名复用、字面量运算化、字符编码”等方法在保守使用的时候和“标识符替换”的通用性应该没有太大差异。不妨一试。
[Bound0 专题列表]QUE SAIS-JE?
生物信息技术支持动漫论坛动漫分享群:45274013

TOP

请问 Javascript 在线混淆器 的代码有提供下载的么?
努力学习中。。。

TOP

引用:
原帖由 bound0 于 2006-9-23 09:05 发表
嗯,的确是刚明白,开始文章看得不够仔细。你们的规则是完全的,已经穷尽了所有的可能。:)

这些研究很有意义(价值)。——加分了!

另外,我现在越来越讨厌自己在三楼说话的口气(当时没觉得),在这里郑重地 ...
只要说得明白就行,我一开始回复的语气也不好,版主还是挺有气量的, 让我们有机会把问题说清楚。

代码混淆方面现在没有进一步的想法了,以后要靠大家努力。

TOP

引用:
原帖由 gway 于 2006-9-23 10:04 发表
请问 Javascript 在线混淆器 的代码有提供下载的么?
没有提供代码下载,但我们会一直提供 Javascript 在线混淆器的服务。

[ 本帖最后由 newwalter 于 2006-9-25 01:25 编辑 ]

TOP