【技术前沿】高手过招 与JS脚本“捉迷藏”
作者:研发部 杨盛海
纯粹的js脚本可以被下载到本地,别人把你辛辛苦苦写出来的代码据为已有,所以网上有很多加密js脚本的方法,然而高手们在研究加密方法同时也指出,绝对安全对js代码来并不可能。因为无论怎么加密,最终你要把加密后的代码通过解密过程在客户端的浏览器中运行起来,也就是说,加密的过程可以不写在目标代码中,而解密过程则必须要写在代码中,否则浏览器没办法执行。
网上介绍的另外一种方法,是将js脚本嵌入到asp代码中,这种办法是否可行尚未验证,毕竟我是php、apache等开源软件的拥护者,对asp不了解。虽然之后获悉安装相关软件apache便能够支持asp,但终因嫌麻烦没有实施。
经过反复思考,我终于悟出一套自己的js加密思路,心中不敢懈怠,赶紧记录下来,害怕这个思路转瞬间被遗忘。
现在,我们先来说加解密过程,如果有一种办法,能够使加解密过程依赖于一个外部数据,在不知道外部数据的情况下,或者即便知道解密算法的情况下也很难破解,那么这个算法就很安全。这个外部数据也称为密钥。这种加密算法在业界应用很多,不用那些已经载入史册的算法,自己现编一个都来得及。
然后,我们把重点回到如何使用一个用户无法获取的外部数据上来。直接在js里面写字符串常量不行,因为js代码是可以被客户端看到,既能看到算法,也能看到密钥。那么,从其它脚本语言中传给js的办法是否可行呢?我第一个想到php,php脚本客户端无法看到,如果能从php传递一个字符串变量给js,那再好不过。经过网络搜寻,看到网上列举不少方法,却都是用明码的方式传递,虽然传了,但可以在js代码中能看到,就失去它做为密钥的意义。接下来从js内部来找问题的解决方案。
在js的文档中搜寻许久,发现有一个属性可以利用,也就是document.file相关的属性,具体来说文档的创建和修改时间,这个用户无法知道。当用户不知道这个密钥,而要破解这个算法,只能是利用所有可能的密钥一个个尝试,密界称之为“暴力破解”,至少几百年的秒数的数字让暴力破解者来尝试,可想是非常安全。
正当我沾沾自喜时,一个念头滑过脑海,用户能不能通过浏览器来得知文档的创建和修改时间呢?赶紧打开浏览器在菜单中搜寻,果然,在文件->属性菜单中,弹出一个对话框,上面赫然列有当前浏览文档的创建和修改日期。这个方法面临被毙的危险,所幸之后没有被我找到如时分秒等表明文档修改时间的数据,也就是时分秒等数据,这才松了口气。
不能用日期,还可以用时间,可以利用一天24小时内的任何一个时间。后来又联想到8小时工作制,文档的修改时间肯定在这8个小时内,计算一下,可供暴力破解的数据为两万多,只要编写一个程序,两万多密钥一会儿就能试完,这样很不保险,如果把开发网页的机器时间调乱呢?比如调为半夜两点钟,把网页的创建时间修改为半夜的时间,这样必须要试到的数据又可以增加到24小时的秒数,达到8万多。这样的程度可以对付一般的用户,因为使用一个稍微复杂一点的算法,比如,验证一个密钥用1秒钟时间,那么验证完所有的密钥需要一天时间,24个小时,再下下功夫,编一个验证一个密钥需要10秒钟时间的解密算法,那就需要10天来验证完所有可能的密钥,恐怕没几个人有那份耐心,况且我写的js代码也不值得花那很长时间来破解。不过话说回来,10秒钟解析一个密码,对使用js程序的用户来说也几乎是一个极限了,因为一个网页从加载到完全打开,用户没有耐心去等待那么长的时间。需要验证的密钥虽多,却仍不保险,只能再想其它的办法。
再之后又找到一种办法,使用页面自动转向的办法,也就是用户键入一个地址时,加载这个网页,而这个网页又加载另外一个网页,同时,用写cookie的方式将数据传给后面加载的网页。尝试之后感觉很好,这样一来,我可以在第一个网页中写上密钥,然后将这个密钥传给后一个网页。写在前一个网页里,用户没办法查看前一个网页的源码,因为在加载第一个页面时,瞬间转向后一个网页。
正当我准备庆祝时,保持冷静的一块大脑区域却又敲响了警钟:如果在IE浏览器中禁止执行js脚本的话,无法转向后一个页面,那就可以查看第一个页面的源码,密钥也就暴露无疑,胜利已经在不远处招唤我,不用明码密钥,那干脆就再使用一次文档修改时间,两个页面的修改时间组合在一起,那就需要8万多再乘上8万多这么多的密钥需要验证。在离胜利最近的地方,我又上网搜索如何能查看网页的修改时间,以保万无一失,结果在一个不起眼的角落,有人做出如下结论,在地址栏中打入javascript:alert(document.lastmodified)就可以看到修改时间,这被称做在地址栏执行脚本。我又被打了一闷棍!在地址栏上可以执行任何脚本,也就意味着可以查看document的任何信息,包括cookie,我的密钥也就没有任何秘密可言了,无奈中还是请出网络,在一藏龙卧虎之站找到屏蔽地址栏脚本的办法。
到目前为止,因为资历尚浅,没有遇到敌方(也就是破解方)的消息,暂且把这当做胜利吧!需要清醒地知道,这仅仅是暂时的胜利,真正高手是隐藏在互联网背后,他们想看你的js文档信息,就像看自己的手心手背一样,不用说这种雕虫小技,估计前面所说的用asp嵌入js代码的方式对他们来说,破解都不是问题。虽然如此,能够有一个自己的加密js的思路,能够对付较低级的破解者,还是值得庆贺。