发现问题 

 

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

在一次偶然中,在爬取某个网站时,老方法,打开调试工具查看请求方式,请求拦截,是否是异步加载,不亦乐乎,当我以为这个网站非常简单的时候,发现二级网页的地址和源码不对应

 

python爬虫破解CryptoJS的aes加密数据 Python 第1张

 

 

 

 

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

 python爬虫破解CryptoJS的aes加密数据 Python 第2张

 

 

 

 

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

 python爬虫破解CryptoJS的aes加密数据 Python 第3张

 

 

 

 

 

用火狐浏览器的event显示:

 python爬虫破解CryptoJS的aes加密数据 Python 第4张

 

 

 

找到加密方式 

 

源码:

 

 python爬虫破解CryptoJS的aes加密数据 Python 第5张

 

 

 

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加密成数组:

 python爬虫破解CryptoJS的aes加密数据 Python 第6张

 

 

 

再对密钥操作:

 python爬虫破解CryptoJS的aes加密数据 Python 第7张

 

 

 

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

 python爬虫破解CryptoJS的aes加密数据 Python 第8张

 

 

 

 

 

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

python爬虫破解CryptoJS的aes加密数据 Python 第9张

 

 

 

我渣一看这种字符串像是base64加密 

 

再将带有/符号的转为^,因为在url编码中,/符号有特殊意义

 python爬虫破解CryptoJS的aes加密数据 Python 第10张

 

 

 

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

 python爬虫破解CryptoJS的aes加密数据 Python 第11张

 

 

 

最后的字符串就是需要的数据了

 

把这段操作封装成一个函数,然后测试:

 python爬虫破解CryptoJS的aes加密数据 Python 第12张

 

 

 

 

经过测试,没毛病,返回的这个字符与真实的一致。

 

卧槽,瞬间激动啦,这还没完,我是直接在当前网页的控制台操作的,换到其他网页的控制台:

 

 python爬虫破解CryptoJS的aes加密数据 Python 第13张

 

 

 

需要两个重要的东西:CryptoJS对象 和 s变量

 

CryptoJS对象都还好,那特么一定是引入的,s变量就难了,从源码找,包含s的太多了,而且还是小写,关键词太多了

 

 

而且S变量是已经定义好的,因为我打开控制台直接访问s就能有结果:

 

 python爬虫破解CryptoJS的aes加密数据 Python 第14张

 

 

 

 

所以,那绝对是已定义的,但是我无法确定是写死的还是随机生成的,如果按写死的来,那就难了,所以我必须找到它,它也至关重要,因为就是aes加密需要的密钥,不然无法加密出来希望的格式

我找了一上午,还请教了我的前端大佬同事,也是一时不知道怎么找

 

 

 

最后,我把当天的任务忙完之后,专门腾出两小时时间来再分析,我一个一个js文件慢慢看:

 

找到key值

 

结果,他么的,放在jquery源码里面:

 

 python爬虫破解CryptoJS的aes加密数据 Python 第15张

 

 

 

 

而且,还真的是写死的

 

卧槽!!!!!!!!!!!!!!!!!!!!,太nm骚了,放源码了,按正常人的惯用思维,像什么jquery,vue等的源码,一定是不敢去乱改的,要写js的话,也不敢去乱搞,都是新建一个js文件写入,它这个把密钥写在jquery源码里,简直反其道而行,我不知道说这个网站的前端开发者是高明还是奇葩了

 

好的,两样东西都齐了,准备用代码实现了,在这之前,先了解下什么是CryptoJS

 

 

 

源码:

 


python爬虫破解CryptoJS的aes加密数据 Python 第16张
!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]找到了刚才那段加密步骤,找了很多解密方法还没发解密

 

 python爬虫破解CryptoJS的aes加密数据 Python 第18张

 

 

 

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

 

 

 python爬虫破解CryptoJS的aes加密数据 Python 第19张

 

 

 

 

那好的,加密过程我们已经知道了

 

用python实现加密解密

 

先选用js2py库来跑js代码:

 python爬虫破解CryptoJS的aes加密数据 Python 第20张

 

 

 

报错,提示没有引入CryptoJS对象

 将crypo-js的源码保存到本地js文件里,放在当前目录,

引入crypo-js,还是不行,我傻了,这个需要在当前环境运行的

 

 python爬虫破解CryptoJS的aes加密数据 Python 第21张

 

 

 

 python爬虫破解CryptoJS的aes加密数据 Python 第22张

 

 

 

 

 

最后,搞来搞去还是没法,这条路走不通了,最后网上查了下,还是有很多人遇到我这样的问题,并且有的已经解决了的,我开始慢慢找跟我的情况一样的,发现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)

 

 运行:

python爬虫破解CryptoJS的aes加密数据 Python 第23张

 

 

 

  

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

 

 python爬虫破解CryptoJS的aes加密数据 Python 第24张

 

 

 

能打开,并且标题与一级网页的标题一致,ok,解码成功,激动!!!!

 

 

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄