- 在模拟登录强智教务系统时,遇到了用户名和密码被JS进行加密提交的问题,加密JavaScript代码如下:
function submitForm1() {
try {
var xh = document.getElementById("userAccount").value;
var pwd = document.getElementById("userPassword").value;
if (xh == "") {
alert("用户名不能为空!");
return false;
}
if (pwd == "") {
alert("密码不能为空!");
return false;
}
var account = encodeInp(xh);
var passwd = encodeInp(pwd);
var encoded = account + "%%%" + passwd;
document.getElementById("encoded").value = encoded;
var jzmmid = document.getElementById("Form1").jzmmid;
return true;
} catch (e) {
alert(e.Message);
return false;
}
}
- 我们首先需要获得该JS加密函数,强智教务的加密算法在 conwork.js里,代码如下:
eval(function (p, a, c, k, e, d) {
e = function (c) {
return (c < a ? "" : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36))
};
if (!''.replace(/^/, String)) {
while (c--)d[e(c)] = k[c] || e(c);
k = [function (e) {
return d[e]
}];
e = function () {
return '\\w+'
};
c = 1;
}
;
while (c--)if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
return p;
}('b 9="o+/=";p q(a){b e="";b 8,5,7="";b f,g,c,1="";b i=0;m{8=a.h(i++);5=a.h(i++);7=a.h(i++);f=8>>2;g=((8&3)<<4)|(5>>4);c=((5&s)<<2)|(7>>6);1=7&t;k(j(5)){c=1=l}v k(j(7)){1=l}e=e+9.d(f)+9.d(g)+9.d(c)+9.d(1);8=5=7="";f=g=c=1=""}u(i
- 可能对js不是很熟的人,看这个也很难看明白,下面我整理成了通用写法,代码如下:
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function encodeInp(input) {
var output = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
do {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64
} else if (isNaN(chr3)) {
enc4 = 64
}
output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4);
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = ""
} while (i < input.length);
return output
}
- 新建一个接口,内部实现和JS函数名相同的抽象方法:
public interface Methods {
public String encodeInp(String input);
}
- Java执行JavaScript函数破解加密算法 ;
/**
* Java执行JavaScript脚本破解加密算法
* @param str
* @return 加密后的字符串
*/
public String playJs(String str) {
// 创建一个脚本引擎管理器
ScriptEngineManager manager = new ScriptEngineManager();
// 获取一个指定的名称的脚本引擎
ScriptEngine engine = manager.getEngineByName("js");
try {
// 获取当前类的所在目录的路径(%20是处理空格)
String path = JsoupCookie.class.getResource("/").getPath().replaceAll("%20", " ");
// FileReader的参数为所要执行的js文件的路径(对空格进行处理)
engine.eval(new FileReader(path + "conwork.js"));
if (engine instanceof Invocable) {
Invocable invocable = (Invocable) engine;
// 从脚本引擎中返回一个给定接口的实现
Methods executeMethod = invocable.getInterface(Methods.class);
// 执行指定的js方法
return executeMethod.encodeInp(str);
}
} catch (Exception e) {
// e.printStackTrace();
}
return null;
}
// 模拟js的charCodeAt()方法
function charCodeAt($str, $index)
{
$char = mb_substr($str, $index, 1, 'UTF-8');
if ($char!=='' && mb_check_encoding($char, 'UTF-8'))
{
$ret = mb_convert_encoding($char, 'UTF-32BE', 'UTF-8');
return hexdec(bin2hex($ret));
} else {
return null;
}
}
// 加密方法
function encodeInp($input)
{
$keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
$output = '';
$i = 0;
do {
$chr1 = charCodeAt($input, $i++);
var_dump($chr1);
$chr2 = charCodeAt($input, $i++);
$chr3 = charCodeAt($input, $i++);
$enc1 = $chr1 >> 2;
$enc2 = (($chr1 & 3) << 4) | ($chr2 >> 4);
$enc3 = (($chr2 & 15) << 2) | ($chr3 >> 6);
$enc4 = $chr3 & 63;
if ($chr2 === null) {
$enc3 = $enc4 = 64;
} else if ($chr3 == null) {
$enc4 = 64;
}
$output = $output . $keyStr[$enc1] . $keyStr[$enc2] . $keyStr[$enc3] . $keyStr[$enc4];
} while ($i < strlen($input));
return $output;
}
echo encodeInp('a123456');
最后: encoded = encodeInp($account) .'%%%' .encodeInp($passwd);