python爬虫破解带有CryptoJS的aes加密的反爬机制
发现问题
在一次偶然中,在爬取某个公开网站(非商业型网站)时,老方法,打开调试工具查看请求方式,请求拦截,是否是异步加载,不亦乐乎,当我以为这个网站非常简单的时候,发现二级网页的地址和源码不对应

Ajax异步加载?源码也是这样的

而且这些链接直接访问根本无法访问

用火狐浏览器的event显示:

找到加密方式
源码:

function() {
var hh = $(this).attr("href");
if (typeof(hh) == 'undefined' || hh == '#') {
return
}
var aa = hh.split("/");
var aaa = aa.length;
var bbb = aa[aaa - 1].split('.');
var ccc = bbb[0];
var cccc = bbb[1];
var r = /^\+?[1-9][0-9]*$/;
if (r.test(ccc) && cccc.indexOf('jhtml') != -1) {
var srcs = CryptoJS.enc.Utf8.parse(ccc);
var k = CryptoJS.enc.Utf8.parse(s);
var en = CryptoJS.AES.encrypt(srcs, k, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
var ddd = en.toString();
ddd = ddd.replace(/\//g, "^");
ddd = ddd.substring(0, ddd.length - 2);
var bbbb = ddd + '.' + bbb[1];
aa[aaa - 1] = bbbb;
var uuu = '';
for (i = 0; i < aaa; i++) {
uuu += aa[i] + '/'
}
uuu = uuu.substring(0, uuu.length - 1);
window.open(uuu)
} else {
var ee = $(this).attr('target');
if (ee.typeof('undefined')) {
window.location = hh
} else {
window.open(hh)
}
}
return false
}
根据我的发现,实现的效果就是让源码的链接:
http://xxxx.xxxx.xx:80/jssfdg/3254639.jhtml
变为如下链接:
http://xxxx.xxxx.xx:80/jssfdg/JzRnGhk7J9D1ZNMlh47fMw.jhtml
以上代码缩减了下:
就这几行代码:
var srcs = CryptoJS.enc.Utf8.parse(ccc);
var k = CryptoJS.enc.Utf8.parse(s);
var en = CryptoJS.AES.encrypt(srcs, k, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
var ddd = en.toString();
ddd = ddd.replace(/\//g, "^");
ddd = ddd.substring(0, ddd.length - 2);
return ddd
将以上代码封装为一个函数并在浏览器的控制台测试:
大概的意思就是先将那串数字用utf8加密成数组:

再对密钥操作:

再将上面的两个数组用aes加密

将用aes加密过的en转为字符串:

我渣一看这种字符串像是base64加密
再将带有/符号的转为^,因为在url编码中,/符号有特殊意义

再将数据后面的[==]分割掉

最后的字符串就是需要的数据了
把这段操作封装成一个函数,然后测试:

经过测试,没毛病,返回的这个字符与真实的一致。
卧槽,瞬间激动啦,这还没完,我是直接在当前网页的控制台操作的,换到其他网页的控制台:

需要两个重要的东西:CryptoJS对象 和 s变量
CryptoJS对象都还好,那特么一定是引入的,s变量就难了,从源码找,包含s的太多了,而且还是小写,关键词太多了
而且S变量是已经定义好的,因为我打开控制台直接访问s就能有结果:

所以,那绝对是已定义的,但是我无法确定是写死的还是随机生成的,如果按写死的来,那就难了,所以我必须找到它,它也至关重要,因为就是aes加密需要的密钥,不然无法加密出来希望的格式
我找了一上午,还请教了我的前端大佬同事,也是一时不知道怎么找
最后,我把当天的任务忙完之后,专门腾出两小时时间来再分析,我一个一个js文件慢慢看:
找到key值
结果,他么的,放在jquery源码里面:

而且,还真的是写死的
卧槽!!!!!!!!!!!!!!!!!!!!,太nm骚了,放源码了,按正常人的惯用思维,像什么jquery,vue等的源码,一定是不敢去乱改的,要写js的话,也不敢去乱搞,都是新建一个js文件写入,它这个把密钥写在jquery源码里,简直反其道而行,我不知道说这个网站的前端开发者是高明还是奇葩了
好的,两样东西都齐了,准备用代码实现了,在这之前,先了解下什么是CryptoJS
源码:
!function(t, n) {
"object" == typeof exports ? module.exports = exports = n() : "function" == typeof define && define.amd ? define([], n) : t.CryptoJS = n()
} (this,
function() {
var t = t ||
function(t, n) {
var i = Object.create ||
function() {
function t() {}
return function(n) {
var i;
return t.prototype = n,
i = new t,
t.prototype = null,
i
}
} (),
e = {},
r = e.lib = {},
o = r.Base = function() {
return {
extend: function(t) {
var n = i(this);
return t && n.mixIn(t),
n.hasOwnProperty("init") && this.init !== n.init || (n.init = function() {
n.$super.init.apply(this, arguments)
}),
n.init.prototype = n,
n.$super = this,
n
},
create: function() {
var t = this.extend();
return t.init.apply(t, arguments),
t
},
init: function() {},
mixIn: function(t) {
for (var n in t) t.hasOwnProperty(n) && (this[n] = t[n]);
t.hasOwnProperty("toString") && (this.toString = t.toString)
},
clone: function() {
return this.init.prototype.extend(this)
}
}
} (),
s = r.WordArray = o.extend({
init: function(t, i) {
t = this.words = t || [],
i != n ? this.sigBytes = i: this.sigBytes = 4 * t.length
},
toString: function(t) {
return (t || c).stringify(this)
},
concat: function(t) {
var n = this.words,
i = t.words,
e = this.sigBytes,
r = t.sigBytes;
if (this.clamp(), e % 4) for (var o = 0; o < r; o++) {
var s = i[o >>> 2] >>> 24 - o % 4 * 8 & 255;
n[e + o >>> 2] |= s << 24 - (e + o) % 4 * 8
} else for (var o = 0; o < r; o += 4) n[e + o >>> 2] = i[o >>> 2];
return this.sigBytes += r,
this
},
clamp: function() {
var n = this.words,
i = this.sigBytes;
n[i >>> 2] &= 4294967295 << 32 - i % 4 * 8,
n.length = t.ceil(i / 4)
},
clone: function() {
var t = o.clone.call(this);
return t.words = this.words.slice(0),
t
},
random: function(n) {
for (var i, e = [], r = function(n) {
var n = n,
i = 987654321,
e = 4294967295;
return function() {
i = 36969 * (65535 & i) + (i >> 16) & e,
n = 18e3 * (65535 & n) + (n >> 16) & e;
var r = (i << 16) + n & e;
return r /= 4294967296,
r += .5,
r * (t.random() > .5 ? 1 : -1)
}
},
o = 0; o < n; o += 4) {
var a = r(4294967296 * (i || t.random()));
i = 987654071 * a(),
e.push(4294967296 * a() | 0)
}
return new s.init(e, n)
}
}),
a = e.enc = {},
c = a.Hex = {
stringify: function(t) {
for (var n = t.words,
i = t.sigBytes,
e = [], r = 0; r < i; r++) {
var o = n[r >>> 2] >>> 24 - r % 4 * 8 & 255;
e.push((o >>> 4).toString(16)),
e.push((15 & o).toString(16))
}
return e.join("")
},
parse: function(t) {
for (var n = t.length,
i = [], e = 0; e < n; e += 2) i[e >>> 3] |= parseInt(t.substr(e, 2), 16) << 24 - e % 8 * 4;
return new s.init(i, n / 2)
}
},
u = a.Latin1 = {
stringify: function(t) {
for (var n = t.words,
i = t.sigBytes,
e = [], r = 0; r < i; r++) {
var o = n[r >>> 2] >>> 24 - r % 4 * 8 & 255;
e.push(String.fromCharCode(o))
}
return e.join("")
},
parse: function(t) {
for (var n = t.length,
i = [], e = 0; e < n; e++) i[e >>> 2] |= (255 & t.charCodeAt(e)) << 24 - e % 4 * 8;
return new s.init(i, n)
}
},
f = a.Utf8 = {
stringify: function(t) {
try {
return decodeURIComponent(escape(u.stringify(t)))
} catch(t) {
throw new Error("Malformed UTF-8 data")
}
},
parse: function(t) {
return u.parse(unescape(encodeURIComponent(t)))
}
},
h = r.BufferedBlockAlgorithm = o.extend({
reset: function() {
this._data = new s.init,
this._nDataBytes = 0
},
_append: function(t) {
"string" == typeof t && (t = f.parse(t)),
this._data.concat(t),
this._nDataBytes += t.sigBytes
},
_process: function(n) {
var i = this._data,
e = i.words,
r = i.sigBytes,
o = this.blockSize,
a = 4 * o,
c = r / a;
c = n ? t.ceil(c) : t.max((0 | c) - this._minBufferSize, 0);
var u = c * o,
f = t.min(4 * u, r);
if (u) {
for (var h = 0; h < u; h += o) this._doProcessBlock(e, h);
var p = e.splice(0, u);
i.sigBytes -= f
}
return new s.init(p, f)
},
clone: function() {
var t = o.clone.call(this);
return t._data = this._data.clone(),
t
},
_minBufferSize: 0
}),
p = (r.Hasher = h.extend({
cfg: o.extend(),
init: function(t) {
this.cfg = this.cfg.extend(t),
this.reset()
},
reset: function() {
h.reset.call(this),
this._doReset()
},
update: function(t) {
return this._append(t),
this._process(),
this
},
finalize: function(t) {
t && this._append(t);
var n = this._doFinalize();
return n
},
blockSize: 16,
_createHelper: function(t) {
return function(n, i) {
return new t.init(i).finalize(n)
}
},
_createHmacHelper: function(t) {
return function(n, i) {
return new p.HMAC.init(t, i).finalize(n)
}
}
}), e.algo = {});
return e
} (Math);
return t
});
//# sourceMappingURL=core.min.js.map
!
function(e, t, i) {
"object" == typeof exports ? module.exports = exports = t(require("./core.min"), require("./sha1.min"), require("./hmac.min")) : "function" == typeof define && define.amd ? define(["./core.min", "./sha1.min", "./hmac.min"], t) : t(e.CryptoJS)
} (this,
function(e) {
return function() {
var t = e,
i = t.lib,
r = i.Base,
n = i.WordArray,
o = t.algo,
a = o.MD5,
c = o.EvpKDF = r.extend({
cfg: r.extend({
keySize: 4,
hasher: a,
iterations: 1
}),
init: function(e) {
this.cfg = this.cfg.extend(e)
},
compute: function(e, t) {
for (var i = this.cfg,
r = i.hasher.create(), o = n.create(), a = o.words, c = i.keySize, f = i.iterations; a.length < c;) {
s && r.update(s);
var s = r.update(e).finalize(t);
r.reset();
for (var u = 1; u < f; u++) s = r.finalize(s),
r.reset();
o.concat(s)
}
return o.sigBytes = 4 * c,
o
}
});
t.EvpKDF = function(e, t, i) {
return c.create(i).compute(e, t)
}
} (),
e.EvpKDF
});
//# sourceMappingURL=evpkdf.min.js.map
!
function(r, e) {
"object" == typeof exports ? module.exports = exports = e(require("./core.min")) : "function" == typeof define && define.amd ? define(["./core.min"], e) : e(r.CryptoJS)
} (this,
function(r) {
return function() {
function e(r, e, t) {
for (var n = [], i = 0, o = 0; o < e; o++) if (o % 4) {
var f = t[r.charCodeAt(o - 1)] << o % 4 * 2,
c = t[r.charCodeAt(o)] >>> 6 - o % 4 * 2;
n[i >>> 2] |= (f | c) << 24 - i % 4 * 8,
i++
}
return a.create(n, i)
}
var t = r,
n = t.lib,
a = n.WordArray,
i = t.enc;
i.Base64 = {
stringify: function(r) {
var e = r.words,
t = r.sigBytes,
n = this._map;
r.clamp();
for (var a = [], i = 0; i < t; i += 3) for (var o = e[i >>> 2] >>> 24 - i % 4 * 8 & 255, f = e[i + 1 >>> 2] >>> 24 - (i + 1) % 4 * 8 & 255, c = e[i + 2 >>> 2] >>> 24 - (i + 2) % 4 * 8 & 255, s = o << 16 | f << 8 | c, h = 0; h < 4 && i + .75 * h < t; h++) a.push(n.charAt(s >>> 6 * (3 - h) & 63));
var p = n.charAt(64);
if (p) for (; a.length % 4;) a.push(p);
return a.join("")
},
parse: function(r) {
var t = r.length,
n = this._map,
a = this._reverseMap;
if (!a) {
a = this._reverseMap = [];
for (var i = 0; i < n.length; i++) a[n.charCodeAt(i)] = i
}
var o = n.charAt(64);
if (o) {
var f = r.indexOf(o);
f !== -1 && (t = f)
}
return e(r, t, a)
},
_map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
}
} (),
r.enc.Base64
});
//# sourceMappingURL=enc-base64.min.js.map
!
function(e, t, r) {
"object" == typeof exports ? module.exports = exports = t(require("./core.min"), require("./evpkdf.min")) : "function" == typeof define && define.amd ? define(["./core.min", "./evpkdf.min"], t) : t(e.CryptoJS)
} (this,
function(e) {
e.lib.Cipher ||
function(t) {
var r = e,
i = r.lib,
n = i.Base,
c = i.WordArray,
o = i.BufferedBlockAlgorithm,
s = r.enc,
a = (s.Utf8, s.Base64),
f = r.algo,
p = f.EvpKDF,
d = i.Cipher = o.extend({
cfg: n.extend(),
createEncryptor: function(e, t) {
return this.create(this._ENC_XFORM_MODE, e, t)
},
createDecryptor: function(e, t) {
return this.create(this._DEC_XFORM_MODE, e, t)
},
init: function(e, t, r) {
this.cfg = this.cfg.extend(r),
this._xformMode = e,
this._key = t,
this.reset()
},
reset: function() {
o.reset.call(this),
this._doReset()
},
process: function(e) {
return this._append(e),
this._process()
},
finalize: function(e) {
e && this._append(e);
var t = this._doFinalize();
return t
},
keySize: 4,
ivSize: 4,
_ENC_XFORM_MODE: 1,
_DEC_XFORM_MODE: 2,
_createHelper: function() {
function e(e) {
return "string" == typeof e ? B: x
}
return function(t) {
return {
encrypt: function(r, i, n) {
return e(i).encrypt(t, r, i, n)
},
decrypt: function(r, i, n) {
return e(i).decrypt(t, r, i, n)
}
}
}
} ()
}),
h = (i.StreamCipher = d.extend({
_doFinalize: function() {
var e = this._process(!0);
return e
},
blockSize: 1
}), r.mode = {}),
u = i.BlockCipherMode = n.extend({
createEncryptor: function(e, t) {
return this.Encryptor.create(e, t)
},
createDecryptor: function(e, t) {
return this.Decryptor.create(e, t)
},
init: function(e, t) {
this._cipher = e,
this._iv = t
}
}),
l = h.CBC = function() {
function e(e, r, i) {
var n = this._iv;
if (n) {
var c = n;
this._iv = t
} else var c = this._prevBlock;
for (var o = 0; o < i; o++) e[r + o] ^= c[o]
}
var r = u.extend();
return r.Encryptor = r.extend({
processBlock: function(t, r) {
var i = this._cipher,
n = i.blockSize;
e.call(this, t, r, n),
i.encryptBlock(t, r),
this._prevBlock = t.slice(r, r + n)
}
}),
r.Decryptor = r.extend({
processBlock: function(t, r) {
var i = this._cipher,
n = i.blockSize,
c = t.slice(r, r + n);
i.decryptBlock(t, r),
e.call(this, t, r, n),
this._prevBlock = c
}
}),
r
} (),
_ = r.pad = {},
v = _.Pkcs7 = {
pad: function(e, t) {
for (var r = 4 * t,
i = r - e.sigBytes % r,
n = i << 24 | i << 16 | i << 8 | i,
o = [], s = 0; s < i; s += 4) o.push(n);
var a = c.create(o, i);
e.concat(a)
},
unpad: function(e) {
var t = 255 & e.words[e.sigBytes - 1 >>> 2];
e.sigBytes -= t
}
},
y = (i.BlockCipher = d.extend({
cfg: d.cfg.extend({
mode: l,
padding: v
}),
reset: function() {
d.reset.call(this);
var e = this.cfg,
t = e.iv,
r = e.mode;
if (this._xformMode == this._ENC_XFORM_MODE) var i = r.createEncryptor;
else {
var i = r.createDecryptor;
this._minBufferSize = 1
}
this._mode && this._mode.__creator == i ? this._mode.init(this, t && t.words) : (this._mode = i.call(r, this, t && t.words), this._mode.__creator = i)
},
_doProcessBlock: function(e, t) {
this._mode.processBlock(e, t)
},
_doFinalize: function() {
var e = this.cfg.padding;
if (this._xformMode == this._ENC_XFORM_MODE) {
e.pad(this._data, this.blockSize);
var t = this._process(!0)
} else {
var t = this._process(!0);
e.unpad(t)
}
return t
},
blockSize: 4
}), i.CipherParams = n.extend({
init: function(e) {
this.mixIn(e)
},
toString: function(e) {
return (e || this.formatter).stringify(this)
}
})),
m = r.format = {},
k = m.OpenSSL = {
stringify: function(e) {
var t = e.ciphertext,
r = e.salt;
if (r) var i = c.create([1398893684, 1701076831]).concat(r).concat(t);
else var i = t;
return i.toString(a)
},
parse: function(e) {
var t = a.parse(e),
r = t.words;
if (1398893684 == r[0] && 1701076831 == r[1]) {
var i = c.create(r.slice(2, 4));
r.splice(0, 4),
t.sigBytes -= 16
}
return y.create({
ciphertext: t,
salt: i
})
}
},
x = i.SerializableCipher = n.extend({
cfg: n.extend({
format: k
}),
encrypt: function(e, t, r, i) {
i = this.cfg.extend(i);
var n = e.createEncryptor(r, i),
c = n.finalize(t),
o = n.cfg;
return y.create({
ciphertext: c,
key: r,
iv: o.iv,
algorithm: e,
mode: o.mode,
padding: o.padding,
blockSize: e.blockSize,
formatter: i.format
})
},
decrypt: function(e, t, r, i) {
i = this.cfg.extend(i),
t = this._parse(t, i.format);
var n = e.createDecryptor(r, i).finalize(t.ciphertext);
return n
},
_parse: function(e, t) {
return "string" == typeof e ? t.parse(e, this) : e
}
}),
g = r.kdf = {},
S = g.OpenSSL = {
execute: function(e, t, r, i) {
i || (i = c.random(8));
var n = p.create({
keySize: t + r
}).compute(e, i),
o = c.create(n.words.slice(t), 4 * r);
return n.sigBytes = 4 * t,
y.create({
key: n,
iv: o,
salt: i
})
}
},
B = i.PasswordBasedCipher = x.extend({
cfg: x.cfg.extend({
kdf: S
}),
encrypt: function(e, t, r, i) {
i = this.cfg.extend(i);
var n = i.kdf.execute(r, e.keySize, e.ivSize);
i.iv = n.iv;
var c = x.encrypt.call(this, e, t, n.key, i);
return c.mixIn(n),
c
},
decrypt: function(e, t, r, i) {
i = this.cfg.extend(i),
t = this._parse(t, i.format);
var n = i.kdf.execute(r, e.keySize, e.ivSize, t.salt);
i.iv = n.iv;
var c = x.decrypt.call(this, e, t, n.key, i);
return c
}
})
} ()
});
//# sourceMappingURL=cipher-core.min.js.map
!
function(e, i) {
"object" == typeof exports ? module.exports = exports = i(require("./core.min")) : "function" == typeof define && define.amd ? define(["./core.min"], i) : i(e.CryptoJS)
} (this,
function(e) { !
function() {
var i = e,
t = i.lib,
n = t.Base,
s = i.enc,
r = s.Utf8,
o = i.algo;
o.HMAC = n.extend({
init: function(e, i) {
e = this._hasher = new e.init,
"string" == typeof i && (i = r.parse(i));
var t = e.blockSize,
n = 4 * t;
i.sigBytes > n && (i = e.finalize(i)),
i.clamp();
for (var s = this._oKey = i.clone(), o = this._iKey = i.clone(), a = s.words, f = o.words, c = 0; c < t; c++) a[c] ^= 1549556828,
f[c] ^= 909522486;
s.sigBytes = o.sigBytes = n,
this.reset()
},
reset: function() {
var e = this._hasher;
e.reset(),
e.update(this._iKey)
},
update: function(e) {
return this._hasher.update(e),
this
},
finalize: function(e) {
var i = this._hasher,
t = i.finalize(e);
i.reset();
var n = i.finalize(this._oKey.clone().concat(t));
return n
}
})
} ()
});
//# sourceMappingURL=hmac.min.js.map
!
function(e, o, r) {
"object" == typeof exports ? module.exports = exports = o(require("./core.min"), require("./cipher-core.min")) : "function" == typeof define && define.amd ? define(["./core.min", "./cipher-core.min"], o) : o(e.CryptoJS)
} (this,
function(e) {
return e.mode.ECB = function() {
var o = e.lib.BlockCipherMode.extend();
return o.Encryptor = o.extend({
processBlock: function(e, o) {
this._cipher.encryptBlock(e, o)
}
}),
o.Decryptor = o.extend({
processBlock: function(e, o) {
this._cipher.decryptBlock(e, o)
}
}),
o
} (),
e.mode.ECB
});
//# sourceMappingURL=mode-ecb.min.js.map
!
function(e, r, i) {
"object" == typeof exports ? module.exports = exports = r(require("./core.min"), require("./cipher-core.min")) : "function" == typeof define && define.amd ? define(["./core.min", "./cipher-core.min"], r) : r(e.CryptoJS)
} (this,
function(e) {
return e.pad.Pkcs7
});
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;
} ('$(E(){$("a").Q(E(){3 6=$(A).x("N");f(z(6)==\'y\'||6==\'#\'){q}3 7=6.p("/");3 c=7.e;3 b=7[c-1].p(\'.\');3 d=b[0];3 n=b[1];3 r=/^\\+?[1-9][0-9]*$/;f(r.F(d)&&n.G(\'I\')!=-1){3 u=8.m.l.v(d);3 k=8.m.l.v(s);3 w=8.H.J(u,k,{t:8.t.K,T:8.U.S});3 4=w.V();4=4.R(/\\//g,"^");4=4.D(0,4.e-2);3 o=4+\'.\'+b[1];7[c-1]=o;3 5=\'\';L(i=0;i<c;i++){5+=7[i]+\'/\'}5=5.D(0,5.e-1);h.j(5)}C{3 B=$(A).x(\'P\');f(B.z(\'y\')){h.O=6}C{h.j(6)}}q M})});', 58, 58, '|||var|ddd|uuu|hh|aa|CryptoJS|||bbb|aaa|ccc|length|if||window||open||Utf8|enc|cccc|bbbb|split|return|||mode|srcs|parse|en|attr|undefined|typeof|this|ee|else|substring|function|test|indexOf|AES|jhtml|encrypt|ECB|for|false|href|location|target|click|replace|Pkcs7|padding|pad|toString'.split('|'), 0, {}));
//# sourceMappingURL=pad-pkcs7.min.js.map
!
function(e, r, i) {
"object" == typeof exports ? module.exports = exports = r(require("./core.min"), require("./enc-base64.min"), require("./md5.min"), require("./evpkdf.min"), require("./cipher-core.min")) : "function" == typeof define && define.amd ? define(["./core.min", "./enc-base64.min", "./md5.min", "./evpkdf.min", "./cipher-core.min"], r) : r(e.CryptoJS)
} (this,
function(e) {
return function() {
var r = e,
i = r.lib,
n = i.BlockCipher,
o = r.algo,
t = [],
c = [],
s = [],
f = [],
a = [],
d = [],
u = [],
v = [],
h = [],
y = []; !
function() {
for (var e = [], r = 0; r < 256; r++) r < 128 ? e[r] = r << 1 : e[r] = r << 1 ^ 283;
for (var i = 0,
n = 0,
r = 0; r < 256; r++) {
var o = n ^ n << 1 ^ n << 2 ^ n << 3 ^ n << 4;
o = o >>> 8 ^ 255 & o ^ 99,
t[i] = o,
c[o] = i;
var p = e[i],
l = e[p],
_ = e[l],
k = 257 * e[o] ^ 16843008 * o;
s[i] = k << 24 | k >>> 8,
f[i] = k << 16 | k >>> 16,
a[i] = k << 8 | k >>> 24,
d[i] = k;
var k = 16843009 * _ ^ 65537 * l ^ 257 * p ^ 16843008 * i;
u[o] = k << 24 | k >>> 8,
v[o] = k << 16 | k >>> 16,
h[o] = k << 8 | k >>> 24,
y[o] = k,
i ? (i = p ^ e[e[e[_ ^ p]]], n ^= e[e[n]]) : i = n = 1
}
} ();
var p = [0, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54],
l = o.AES = n.extend({
_doReset: function() {
if (!this._nRounds || this._keyPriorReset !== this._key) {
for (var e = this._keyPriorReset = this._key,
r = e.words,
i = e.sigBytes / 4,
n = this._nRounds = i + 6,
o = 4 * (n + 1), c = this._keySchedule = [], s = 0; s < o; s++) if (s < i) c[s] = r[s];
else {
var f = c[s - 1];
s % i ? i > 6 && s % i == 4 && (f = t[f >>> 24] << 24 | t[f >>> 16 & 255] << 16 | t[f >>> 8 & 255] << 8 | t[255 & f]) : (f = f << 8 | f >>> 24, f = t[f >>> 24] << 24 | t[f >>> 16 & 255] << 16 | t[f >>> 8 & 255] << 8 | t[255 & f], f ^= p[s / i | 0] << 24),
c[s] = c[s - i] ^ f
}
for (var a = this._invKeySchedule = [], d = 0; d < o; d++) {
var s = o - d;
if (d % 4) var f = c[s];
else var f = c[s - 4];
d < 4 || s <= 4 ? a[d] = f: a[d] = u[t[f >>> 24]] ^ v[t[f >>> 16 & 255]] ^ h[t[f >>> 8 & 255]] ^ y[t[255 & f]]
}
}
},
encryptBlock: function(e, r) {
this._doCryptBlock(e, r, this._keySchedule, s, f, a, d, t)
},
decryptBlock: function(e, r) {
var i = e[r + 1];
e[r + 1] = e[r + 3],
e[r + 3] = i,
this._doCryptBlock(e, r, this._invKeySchedule, u, v, h, y, c);
var i = e[r + 1];
e[r + 1] = e[r + 3],
e[r + 3] = i
},
_doCryptBlock: function(e, r, i, n, o, t, c, s) {
for (var f = this._nRounds,
a = e[r] ^ i[0], d = e[r + 1] ^ i[1], u = e[r + 2] ^ i[2], v = e[r + 3] ^ i[3], h = 4, y = 1; y < f; y++) {
var p = n[a >>> 24] ^ o[d >>> 16 & 255] ^ t[u >>> 8 & 255] ^ c[255 & v] ^ i[h++],
l = n[d >>> 24] ^ o[u >>> 16 & 255] ^ t[v >>> 8 & 255] ^ c[255 & a] ^ i[h++],
_ = n[u >>> 24] ^ o[v >>> 16 & 255] ^ t[a >>> 8 & 255] ^ c[255 & d] ^ i[h++],
k = n[v >>> 24] ^ o[a >>> 16 & 255] ^ t[d >>> 8 & 255] ^ c[255 & u] ^ i[h++];
a = p,
d = l,
u = _,
v = k
}
var p = (s[a >>> 24] << 24 | s[d >>> 16 & 255] << 16 | s[u >>> 8 & 255] << 8 | s[255 & v]) ^ i[h++],
l = (s[d >>> 24] << 24 | s[u >>> 16 & 255] << 16 | s[v >>> 8 & 255] << 8 | s[255 & a]) ^ i[h++],
_ = (s[u >>> 24] << 24 | s[v >>> 16 & 255] << 16 | s[a >>> 8 & 255] << 8 | s[255 & d]) ^ i[h++],
k = (s[v >>> 24] << 24 | s[a >>> 16 & 255] << 16 | s[d >>> 8 & 255] << 8 | s[255 & u]) ^ i[h++];
e[r] = p,
e[r + 1] = l,
e[r + 2] = _,
e[r + 3] = k
},
keySize: 8
});
r.AES = n._createHelper(l)
} (),
e.AES
});
//# sourceMappingURL=aes.min.js.map
!
function(e, n) {
"object" == typeof exports ? module.exports = exports = n(require("./core.min")) : "function" == typeof define && define.amd ? define(["./core.min"], n) : n(e.CryptoJS)
} (this,
function(e) {
return e.enc.Utf8
});
aes加密源码
源码看半天看不懂,我高估了我自己,我搜[ccc]找到了刚才那段加密步骤,找了很多解密方法还没发解密

这里强烈推荐火狐浏览器,就是他妈的牛逼,用火狐可以嗅探到js的事件,而且还显示解密过的js,对的,就是最开始那段代码,具体往上滑,还可以看到源码,以及这段代码在源码文件的哪个位置

那好的,加密过程我们已经知道了
用python实现加密解密
先选用js2py库来跑js代码:

报错,提示没有引入CryptoJS对象
将crypo-js的源码保存到本地js文件里,放在当前目录,
引入crypo-js,还是不行,我傻了,这个需要在当前环境运行的


最后,搞来搞去还是没法,这条路走不通了,最后网上查了下,还是有很多人遇到我这样的问题,并且有的已经解决了的,我开始慢慢找跟我的情况一样的,发现python自己有一个加密库—— Crypto
我研究了半天这个库,pypi文档上看了一遍也没发现个什么东西,跟我用来解密还是有些距离
真的没法了吗?
我想了半天,我觉得我都已经到这一步了,为什么还是不行,一定有我没注意到的情况,最后网上找了很多篇相关的文章,找到如下代码可行,但是到底是哪篇文章我已经不知道了,感谢这位老哥,源地址我真找不到了:
from Crypto.Cipher import AES
import base64 def add_to_16(s):
while len(s) % 16 != 0:
s += (16 - len(s) % 16) * chr(16 - len(s) % 16)
return str.encode(s) # 返回bytes def get_secret_url(text, key='qnbyzzwmdgghmcnm'):
aes = AES.new(str.encode(key), AES.MODE_ECB) # 初始化加密器,本例采用ECB加密模式
encrypted_text = str(base64.encodebytes(aes.encrypt(add_to_16(text))), encoding='utf8').replace('\n', '') # 加密
encrypted_text = encrypted_text.replace('/', "^") # ddd.replace(/\//g, "^")
return encrypted_text[:-2] def get_real_url(first_url, key):
aa = first_url.split('/')
aaa = len(aa)
bbb = aa[aaa - 1].split('.')
ccc = bbb[0]
secret_text = get_secret_url(ccc, key=key)
return first_url.replace(ccc, secret_text) url = 'http://xxx.xxxx.xxx.xxx.cn:80/xxxx/938848.jhtml'
key = 'qnbyzzwmdgghmcnm' # 此处问加密key值
url = get_real_url(url, key=key)
print(url)
运行:

复制这个链接用浏览器打开:

能打开,并且标题与一级网页的标题一致,ok,解码成功,激动!!!!
python爬虫破解带有CryptoJS的aes加密的反爬机制的更多相关文章
- python爬虫破解带有RSA.js的RSA加密数据的反爬机制
前言 同上一篇的aes加密一样,也是偶然发现这个rsa加密的,目标网站我就不说了,保密. 当我发现这个网站是ajax加载时: 我已经习以为常,正在进行爬取时,发现返回为空,我开始用findler抓包, ...
- Python爬虫—破解JS加密的Cookie
前言 在GitHub上维护了一个代理池的项目,代理来源是抓取一些免费的代理发布网站.上午有个小哥告诉我说有个代理抓取接口不能用了,返回状态521.抱着帮人解决问题的心态去跑了一遍代码.发现果真是这样. ...
- python爬虫---详解爬虫分类,HTTP和HTTPS的区别,证书加密,反爬机制和反反爬策略,requests模块的使用,常见的问题
python爬虫---详解爬虫分类,HTTP和HTTPS的区别,证书加密,反爬机制和反反爬策略,requests模块的使用,常见的问题 一丶爬虫概述 通过编写程序'模拟浏览器'上网,然后通 ...
- 第三百四十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—cookie禁用、自动限速、自定义spider的settings,对抗反爬机制
第三百四十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—cookie禁用.自动限速.自定义spider的settings,对抗反爬机制 cookie禁用 就是在Scrapy的配置文件set ...
- python爬虫---CrawlSpider实现的全站数据的爬取,分布式,增量式,所有的反爬机制
CrawlSpider实现的全站数据的爬取 新建一个工程 cd 工程 创建爬虫文件:scrapy genspider -t crawl spiderName www.xxx.com 连接提取器Link ...
- Python爬虫实战——反爬机制的解决策略【阿里】
这一次呢,让我们来试一下"CSDN热门文章的抓取". 话不多说,让我们直接进入CSND官网. (其实是因为我被阿里的反爬磨到没脾气,不想说话--) 一.URL分析 输入" ...
- 关于使用scrapy框架编写爬虫以及Ajax动态加载问题、反爬问题解决方案
Python爬虫总结 总的来说,Python爬虫所做的事情分为两个部分,1:将网页的内容全部抓取下来,2:对抓取到的内容和进行解析,得到我们需要的信息. 目前公认比较好用的爬虫框架为Scrapy,而且 ...
- 爬虫入门到放弃系列07:js混淆、eval加密、字体加密三大反爬技术
前言 如果再说IP请求次数检测.验证码这种最常见的反爬虫技术,可能大家听得耳朵都出茧子了.当然,也有的同学写了了几天的爬虫,觉得爬虫太简单.没有啥挑战性.所以特地找了三个有一定难度的网站,希望可以有兴 ...
- Python 爬虫工程师必看,深入解读字体反爬虫
字体反爬虫开篇概述 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那么针对这三类人 ...
随机推荐
- UML图的种类
一.作为一种建模语言,UML的定义包括UML语义和UML表示法两个部分. UML语义:描述基于UML的精确元模型定义. UML表示法:定义UML符号的表示法,为开发者或开发工具使用这些图形符号和文本语 ...
- HDU - 5586 Sum(区间增量最大)
题意:将数组A的部分区间值按照函数f(Ai)=(1890*Ai+143)mod10007修改值,区间长度可以为0,问该操作后数组A的最大值. 分析:先求出每个元素的增量,进而求出增量和.通过b[r]- ...
- UVA - 10539 Almost Prime Numbers (几乎是素数)
题意:输入两个正整数L.U(L<=U<1012),统计区间[L,U]的整数中有多少个数满足:它本身不是素数,但只有一个素因子. 分析: 1.满足条件的数是素数的倍数. 2.枚举所有的素数, ...
- js连续的日期判断,判断相差几天
var startTime=Date.parse(new Date('2020-02-28')); var endTime=Date.parse(new Date('2020-02-29')); $. ...
- Spring耗时拦截器(url,restful)
import java.io.IOException; import java.util.Date; import javax.servlet.Filter; import javax.servlet ...
- 吴裕雄--天生自然TensorFlow2教程:高阶操作
import tensorflow as tf a = tf.random.normal([3, 3]) a mask = a > 0 mask # 为True元素,即>0的元素的索引 i ...
- 2020/1/30 PHP代码审计之CSRF漏洞
0x00 CSRF漏洞 CSRF(Cross-site request forgery)跨站请求伪造:也被称为"One Click Attack"或者Session Riding, ...
- 使用NtQueryInformationFile函数获得不到完整路径
#include <windows.h> #include <iostream> using namespace std; typedef struct _OBJECT_NAM ...
- APP测试关注的点 - 笔记
来源公开课笔记!!! 1.黑盒测试 是否正确并如设计的一样正常运行.测试自动化回归测试 2.测试主要关注参数: CPU.内存.耗电量.流量.FRS(流畅度).同时关注APP安装耗时和启动耗时 3.适配 ...
- Ubuntu Kylin 14.04LTS 开机后卡在登陆界面,可以进入字符界面,或者登陆后鼠标不显示但是管用
2014年4月27日,距离中期检查还有七天,基本上什么也没做,特别着急,雨已经下了快一天了,中午用美团外卖定的黄焖排骨,MD,什么玩意,那么一点点就18块钱,一看就不值五块钱,发誓再也不吃,最重要的是 ...