不可逆JS加密!JShaman加密的JS代码能被解密还原吗?

JS代码加密,最担心的是:加密后的JS代码,会被还原为原本的代码吗?
众所周知,国内最知名的JS加密当属JShaman,今天,我们就以JShaman加密的Js代码为例,测试一下JShaman加密后的代码是否能被还原。

1、首先,使用JShaman(www.jshaman.com)进行一段JS代码加密。
原始代码就用Jshaman提供的例程:

function hello_world(){
alert("hello world");
}
hello_world();



不可逆JS加密!JShaman加密的JS代码能被解密还原吗?



使用默认配置项,加密后生成的代码为:

var _0x5f2d=['hello\x20world'];(function(_0x1d7bcc,_0x3c8ae3){var _0x51bb3c=function(_0x1df202){while(--_0x1df202){_0x1d7bcc['\x70\x75\x73\x68'](_0x1d7bcc['\x73\x68\x69\x66\x74']());}};_0x51bb3c(++_0x3c8ae3);}(_0x5f2d,0x121));var _0xd5f2=function(_0x32a75d,_0x18d324){_0x32a75d=_0x32a75d-0x0;var _0x462cef=_0x5f2d[_0x32a75d];return _0x462cef;};function hello_world(){alert(_0xd5f2('0x0'));}hello_world();

2、解密还原
解密还原JS代码,这里在nodejs的环境下使用esprima和escodegen(http://esprima.org/);

首先安装这两个组件:

npm install esprima
npm install escodegen

然后准备以下代码:

var esprima = require('esprima')
var escodegen = require('escodegen')

//参数context是要格式的js
function formatJS(content){
var ast=esprima.parseScript(content.toString());
var ast_to_json=JSON.stringify(ast);
console.log(ast_to_json);
var ast1=JSON.parse(ast_to_json);
var code=escodegen.generate(ast1);
console.log("");
console.log(code);
return code;
}

//上面代码中加密后的JS代码
var s="var _0x5f2d=['hello\x20world'];(function(_0x1d7bcc,_0x3c8ae3){var _0x51bb3c=function(_0x1df202){while(--_0x1df202){_0x1d7bcc['\x70\x75\x73\x68'](_0x1d7bcc['\x73\x68\x69\x66\x74']());}};_0x51bb3c(++_0x3c8ae3);}(_0x5f2d,0x121));var _0xd5f2=function(_0x32a75d,_0x18d324){_0x32a75d=_0x32a75d-0x0;var _0x462cef=_0x5f2d[_0x32a75d];return _0x462cef;};function hello_world(){alert(_0xd5f2('0x0'));}hello_world();";

formatJS(s);

用node执行,效果如下:



不可逆JS加密!JShaman加密的JS代码能被解密还原吗?



解密还原出的JS代码是:

var _0x5f2d = ['hello world'];
(function (_0x1d7bcc, _0x3c8ae3) {
var _0x51bb3c = function (_0x1df202) {
while (--_0x1df202) {
_0x1d7bcc['push'](_0x1d7bcc['shift']());
}
};
_0x51bb3c(++_0x3c8ae3);
}(_0x5f2d, 289));
var _0xd5f2 = function (_0x32a75d, _0x18d324) {
_0x32a75d = _0x32a75d - 0;
var _0x462cef = _0x5f2d[_0x32a75d];
return _0x462cef;
};
function hello_world() {
alert(_0xd5f2('0x0'));
}
hello_world();

3、修改Jshaman配置,提高保护强度,配置如下:



不可逆JS加密!JShaman加密的JS代码能被解密还原吗?



再次进行js代码加密,得到加密js代码如下:



不可逆JS加密!JShaman加密的JS代码能被解密还原吗?



显然这次加密后的代码更复杂,接下来再进行还原,看效果如何。

4、再次使用上面的方法对这段新的代码进行解密还原,结果如下:

var _0x0e06 = [
'Qnd0',
'aGVsbG8gd29ybGQ='
];
(function (_0x222c83, _0x572f23) {
var _0x47c274 = function (_0x212fa5) {
while (--_0x212fa5) {
_0x222c83['push'](_0x222c83['shift']());
}
};
_0x47c274(++_0x572f23);
}(_0x0e06, 490));
var _0x60e0 = function (_0x12c47f, _0x32a6b6) {
_0x12c47f = _0x12c47f - 0;
var _0x4e0aed = _0x0e06[_0x12c47f];
if (_0x60e0['initialized'] === undefined) {
(function () {
var _0x39cd1d = Function('return (function () ' + '{}.constructor("return this")()' + ');');
var _0x24f625 = _0x39cd1d();
var _0x43d027 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
_0x24f625['atob'] || (_0x24f625['atob'] = function (_0x245d5c) {
var _0x20b859 = String(_0x245d5c)['replace'](/=+$/, '');
for (var _0x1849e7 = 0, _0x40b523, _0x398755, _0xe95143 = 0, _0x3e3a3e = ''; _0x398755 = _0x20b859['char
At'](_0xe95143++); ~_0x398755 && (_0x40b523 = _0x1849e7 % 4 ? _0x40b523 * 64 + _0x398755 : _0x398755, _0x1849e7++ % 4) ?
_0x3e3a3e += String['fromCharCode'](255 & _0x40b523 >> (-2 * _0x1849e7 & 6)) : 0) {
_0x398755 = _0x43d027['indexOf'](_0x398755);
}
return _0x3e3a3e;
});
}());
_0x60e0['base64DecodeUnicode'] = function (_0x47956f) {
var _0x344ddc = atob(_0x47956f);
var _0x51894e = [];
for (var _0x58f1fe = 0, _0x17faff = _0x344ddc['length']; _0x58f1fe < _0x17faff; _0x58f1fe++) {
_0x51894e += '%' + ('00' + _0x344ddc['charCodeAt'](_0x58f1fe)['toString'](16))['slice'](-2);
}
return decodeURIComponent(_0x51894e);
};
_0x60e0['data'] = {};
_0x60e0['initialized'] = !![];
}
if (_0x60e0['data'][_0x12c47f] === undefined) {
_0x4e0aed = _0x60e0['base64DecodeUnicode'](_0x4e0aed);
_0x60e0['data'][_0x12c47f] = _0x4e0aed;
} else {
_0x4e0aed = _0x60e0['data'][_0x12c47f];
}
return _0x4e0aed;
};
function hello_world() {
var _0x31675d = {
'Bwt': function _0x19c008(_0x3b55b5, _0x1b7275) {
return _0x3b55b5(_0x1b7275);
}
};
_0x31675d[_0x60e0('0x0')](alert, _0x60e0('0x1'));
}
hello_world();



不可逆JS加密!JShaman加密的JS代码能被解密还原吗?



可见。JShaman加密后的代码,即使解密还原,与加密前的加代相比,差别也非常之大,相比之下多了很多复杂的逻辑关系,字符也是混乱不堪,代码几乎仍是无法阅读,更别说理解代理含义了。可见JShaman可以说是实现了不可逆加密,加密后的代码是不可解密还原的。

当然,可能有人会说,只要我肯花时间,一点点的读,也是能把代码理解的。是的,从原理上来说,这么说也没错,但是原本4行代码,只需要1分钟就可以读懂,加密后的代码,却需要30分钟才能大概看明白,时间成本上升几十倍。而这只是个4行代码的示例,如果是真实的项目或产品代码,可能代码有数千行,甚至几万行。那么加密后的代码,如果想要解读一次,可能需要用几个月甚至几年时间。如果有这能力、肯费这劲,那还不如自己开发呢...这是否让人望而却步?现实的说:JS代码保护的效果达到了。