【Python3爬虫】破解时光网登录加密参数并实现模拟登录

一、站点分析

MTime 时光网是一个电影媒体与电商服务平台,而这次做的模拟登录则是依靠其手机端站点,站点地址为: https://m.mtime.cn/# 。切换到登录页面,再分别输入账号和错误的密码,点击登录,登录失败,截图如下:

打开开发者工具, 选择“Network”,切换到“XHR”选项,找到一条名为 login.api 的请求,打开后可以发现就是登录所发送的请求,再查看该请求的参数部分,截图如下:

二、参数破解

1.参数分析

经过前面的分析可知有五个参数需要获取,分别是 t、name、password、code 和 codeId,其中 code 和 codeId 目前看来是空的,无须处理,而 name 就是输入的手机号,password 应该是输入的密码加密后的结果,剩下一个 t 还不知道是什么含义。

2.参数获取

在开发者工具中,Ctrl + F 全局搜索“password”,找到如下的 JavaScript 文件:

https://static3.mtime.cn/html5/20200116143308/js/views/member/signin.js

打开该文件后搜索“password”,首先是获取 name 属性为“password”的输入框,在下文中还发现了 vcode 和 vcodeId,这两个就是后面请求所需的 code 和 vcode 参数的值,截图如下:

继续搜索“password”,可以找到一个 getPassword() 方法,用于获取输入的密码内容,截图如下:

接着搜索“password”,找到如下内容:

这就是登录请求时的参数部分,其中密码 password 是将输入的密码进行加密后的结果,使用的是 f.desEcbPkcs7 方法,那这个方法具体是什么呢?

3.加密方法

在上面的 JS 文件中的 217 行打上断点,然后刷新页面并重新登录,页面会进入 debugger 模式,然后选中 desEcbPkcs7 部分,点击后跳转到 app.all.min.js 中的如下代码部分:

这个 af 函数就是加密方法了,其中用到了一个变量 CryptoJS,要获取这个变量的定义,就在上面代码中的1033行打上断点,再重新登录一遍,定位到 CryptoJS 的定义部分,截图如下:

对于变量 CryptoJS 的定义包含在 libs.all.min.js 中,但这个文件中的代码量比较大,若全部复制下来使用会不方便,而我们也只需要得到对变量 CryptoJS 进行定义的代码就够了,所以建议先把该 JS 文件保存到本地,再用编辑器打开,就能很快地得到我们所需要的代码了,即使如此还是有一千四百多行(汗~)。


   1 var CryptoJS = CryptoJS || function (g, w) {
   2     var m = {}
   3         , q = m.lib = {}
   4         , j = q.Base = function () {
   5         function a() {
   6         }
   7 
   8         return {
   9             extend: function (e) {
  10                 a.prototype = this;
  11                 var c = new a;
  12                 return e && c.mixIn(e),
  13                     c.$super = this,
  14                     c
  15             },
  16             create: function () {
  17                 var c = this.extend();
  18                 return c.init.apply(c, arguments),
  19                     c
  20             },
  21             init: function () {
  22             },
  23             mixIn: function (c) {
  24                 for (var f in c) {
  25                     c.hasOwnProperty(f) && (this[f] = c[f])
  26                 }
  27                 c.hasOwnProperty("toString") && (this.toString = c.toString)
  28             },
  29             clone: function () {
  30                 return this.$super.extend(this)
  31             }
  32         }
  33     }()
  34         , v = q.WordArray = j.extend({
  35         init: function (a, c) {
  36             a = this.words = a || [],
  37                 this.sigBytes = c != w ? c : 4 * a.length
  38         },
  39         toString: function (a) {
  40             return (a || x).stringify(this)
  41         },
  42         concat: function (a) {
  43             var o = this.words
  44                 , f = a.words
  45                 , l = this.sigBytes
  46                 , a = a.sigBytes;
  47             this.clamp();
  48             if (l % 4) {
  49                 for (var c = 0; c >> 2] |= (f[c >>> 2] >>> 24 - 8 * (c % 4) & 255) << 24 - 8 * ((l + c) % 4)
  51                 }
  52             } else {
  53                 if (65535 < f.length) {
  54                     for (c = 0; c >> 2] = f[c >>> 2]
  56                     }
  57                 } else {
  58                     o.push.apply(o, f)
  59                 }
  60             }
  61             return this.sigBytes += a,
  62                 this
  63         },
  64         clamp: function () {
  65             var c = this.words
  66                 , a = this.sigBytes;
  67             c[a >>> 2] &= 4294967295 << 32 - 8 * (a % 4),
  68                 c.length = g.ceil(a / 4)
  69         },
  70         clone: function () {
  71             var a = j.clone.call(this);
  72             return a.words = this.words.slice(0),
  73                 a
  74         },
  75         random: function (e) {
  76             for (var a = [], c = 0; c < e; c += 4) {
  77                 a.push(4294967296 * g.random() | 0)
  78             }
  79             return v.create(a, e)
  80         }
  81     })
  82         , p = m.enc = {}
  83         , x = p.Hex = {
  84         stringify: function (a) {
  85             for (var o = a.words, a = a.sigBytes, f = [], l = 0; l >> 2] >>> 24 - 8 * (l % 4) & 255;
  87                 f.push((c >>> 4).toString(16)),
  88                     f.push((c & 15).toString(16))
  89             }
  90             return f.join("")
  91         },
  92         parse: function (a) {
  93             for (var i = a.length, c = [], f = 0; f >> 3] |= parseInt(a.substr(f, 2), 16) << 24 - 4 * (f % 8)
  95             }
  96             return v.create(c, i / 2)
  97         }
  98     }
  99         , b = p.Latin1 = {
 100         stringify: function (a) {
 101             for (var i = a.words, a = a.sigBytes, c = [], f = 0; f >> 2] >>> 24 - 8 * (f % 4) & 255))
 103             }
 104             return c.join("")
 105         },
 106         parse: function (a) {
 107             for (var i = a.length, c = [], f = 0; f >> 2] |= (a.charCodeAt(f) & 255) << 24 - 8 * (f % 4)
 109             }
 110             return v.create(c, i)
 111         }
 112     }
 113         , h = p.Utf8 = {
 114         stringify: function (a) {
 115             try {
 116                 return decodeURIComponent(escape(b.stringify(a)))
 117             } catch (c) {
 118                 throw Error("Malformed UTF-8 data")
 119             }
 120         },
 121         parse: function (a) {
 122             return b.parse(unescape(encodeURIComponent(a)))
 123         }
 124     }
 125         , k = q.BufferedBlockAlgorithm = j.extend({
 126         reset: function () {
 127             this._data = v.create(),
 128                 this._nDataBytes = 0
 129         },
 130         _append: function (a) {
 131             "string" == typeof a && (a = h.parse(a)),
 132                 this._data.concat(a),
 133                 this._nDataBytes += a.sigBytes
 134         },
 135         _process: function (y) {
 136             var f = this._data
 137                 , s = f.words
 138                 , e = f.sigBytes
 139                 , l = this.blockSize
 140                 , z = e / (4 * l)
 141                 , z = y ? g.ceil(z) : g.max((z | 0) - this._minBufferSize, 0)
 142                 , y = z * l
 143                 , e = g.min(4 * y, e);
 144             if (y) {
 145                 for (var c = 0; c < y; c += l) {
 146                     this._doProcessBlock(s, c)
 147                 }
 148                 c = s.splice(0, y),
 149                     f.sigBytes -= e
 150             }
 151             return v.create(c, e)
 152         },
 153         clone: function () {
 154             var a = j.clone.call(this);
 155             return a._data = this._data.clone(),
 156                 a
 157         },
 158         _minBufferSize: 0
 159     });
 160     q.Hasher = k.extend({
 161         init: function () {
 162             this.reset()
 163         },
 164         reset: function () {
 165             k.reset.call(this),
 166                 this._doReset()
 167         },
 168         update: function (a) {
 169             return this._append(a),
 170                 this._process(),
 171                 this
 172         },
 173         finalize: function (a) {
 174             return a && this._append(a),
 175                 this._doFinalize(),
 176                 this._hash
 177         },
 178         clone: function () {
 179             var a = k.clone.call(this);
 180             return a._hash = this._hash.clone(),
 181                 a
 182         },
 183         blockSize: 16,
 184         _createHelper: function (a) {
 185             return function (e, c) {
 186                 return a.create(c).finalize(e)
 187             }
 188         },
 189         _createHmacHelper: function (a) {
 190             return function (e, c) {
 191                 return d.HMAC.create(a, c).finalize(e)
 192             }
 193         }
 194     });
 195     var d = m.algo = {};
 196     return m
 197 }(Math)
 198     , CryptoJS = CryptoJS || function (g, w) {
 199     var m = {}
 200         , q = m.lib = {}
 201         , j = q.Base = function () {
 202         function a() {
 203         }
 204 
 205         return {
 206             extend: function (e) {
 207                 a.prototype = this;
 208                 var c = new a;
 209                 return e && c.mixIn(e),
 210                     c.$super = this,
 211                     c
 212             },
 213             create: function () {
 214                 var c = this.extend();
 215                 return c.init.apply(c, arguments),
 216                     c
 217             },
 218             init: function () {
 219             },
 220             mixIn: function (c) {
 221                 for (var f in c) {
 222                     c.hasOwnProperty(f) && (this[f] = c[f])
 223                 }
 224                 c.hasOwnProperty("toString") && (this.toString = c.toString)
 225             },
 226             clone: function () {
 227                 return this.$super.extend(this)
 228             }
 229         }
 230     }()
 231         , v = q.WordArray = j.extend({
 232         init: function (a, c) {
 233             a = this.words = a || [],
 234                 this.sigBytes = c != w ? c : 4 * a.length
 235         },
 236         toString: function (a) {
 237             return (a || x).stringify(this)
 238         },
 239         concat: function (a) {
 240             var o = this.words
 241                 , f = a.words
 242                 , l = this.sigBytes
 243                 , a = a.sigBytes;
 244             this.clamp();
 245             if (l % 4) {
 246                 for (var c = 0; c >> 2] |= (f[c >>> 2] >>> 24 - 8 * (c % 4) & 255) << 24 - 8 * ((l + c) % 4)
 248                 }
 249             } else {
 250                 if (65535 < f.length) {
 251                     for (c = 0; c >> 2] = f[c >>> 2]
 253                     }
 254                 } else {
 255                     o.push.apply(o, f)
 256                 }
 257             }
 258             return this.sigBytes += a,
 259                 this
 260         },
 261         clamp: function () {
 262             var c = this.words
 263                 , a = this.sigBytes;
 264             c[a >>> 2] &= 4294967295 << 32 - 8 * (a % 4),
 265                 c.length = g.ceil(a / 4)
 266         },
 267         clone: function () {
 268             var a = j.clone.call(this);
 269             return a.words = this.words.slice(0),
 270                 a
 271         },
 272         random: function (e) {
 273             for (var a = [], c = 0; c < e; c += 4) {
 274                 a.push(4294967296 * g.random() | 0)
 275             }
 276             return v.create(a, e)
 277         }
 278     })
 279         , p = m.enc = {}
 280         , x = p.Hex = {
 281         stringify: function (a) {
 282             for (var o = a.words, a = a.sigBytes, f = [], l = 0; l >> 2] >>> 24 - 8 * (l % 4) & 255;
 284                 f.push((c >>> 4).toString(16)),
 285                     f.push((c & 15).toString(16))
 286             }
 287             return f.join("")
 288         },
 289         parse: function (a) {
 290             for (var i = a.length, c = [], f = 0; f >> 3] |= parseInt(a.substr(f, 2), 16) << 24 - 4 * (f % 8)
 292             }
 293             return v.create(c, i / 2)
 294         }
 295     }
 296         , b = p.Latin1 = {
 297         stringify: function (a) {
 298             for (var i = a.words, a = a.sigBytes, c = [], f = 0; f >> 2] >>> 24 - 8 * (f % 4) & 255))
 300             }
 301             return c.join("")
 302         },
 303         parse: function (a) {
 304             for (var i = a.length, c = [], f = 0; f >> 2] |= (a.charCodeAt(f) & 255) << 24 - 8 * (f % 4)
 306             }
 307             return v.create(c, i)
 308         }
 309     }
 310         , h = p.Utf8 = {
 311         stringify: function (a) {
 312             try {
 313                 return decodeURIComponent(escape(b.stringify(a)))
 314             } catch (c) {
 315                 throw Error("Malformed UTF-8 data")
 316             }
 317         },
 318         parse: function (a) {
 319             return b.parse(unescape(encodeURIComponent(a)))
 320         }
 321     }
 322         , k = q.BufferedBlockAlgorithm = j.extend({
 323         reset: function () {
 324             this._data = v.create(),
 325                 this._nDataBytes = 0
 326         },
 327         _append: function (a) {
 328             "string" == typeof a && (a = h.parse(a)),
 329                 this._data.concat(a),
 330                 this._nDataBytes += a.sigBytes
 331         },
 332         _process: function (y) {
 333             var f = this._data
 334                 , s = f.words
 335                 , e = f.sigBytes
 336                 , l = this.blockSize
 337                 , z = e / (4 * l)
 338                 , z = y ? g.ceil(z) : g.max((z | 0) - this._minBufferSize, 0)
 339                 , y = z * l
 340                 , e = g.min(4 * y, e);
 341             if (y) {
 342                 for (var c = 0; c < y; c += l) {
 343                     this._doProcessBlock(s, c)
 344                 }
 345                 c = s.splice(0, y),
 346                     f.sigBytes -= e
 347             }
 348             return v.create(c, e)
 349         },
 350         clone: function () {
 351             var a = j.clone.call(this);
 352             return a._data = this._data.clone(),
 353                 a
 354         },
 355         _minBufferSize: 0
 356     });
 357     q.Hasher = k.extend({
 358         init: function () {
 359             this.reset()
 360         },
 361         reset: function () {
 362             k.reset.call(this),
 363                 this._doReset()
 364         },
 365         update: function (a) {
 366             return this._append(a),
 367                 this._process(),
 368                 this
 369         },
 370         finalize: function (a) {
 371             return a && this._append(a),
 372                 this._doFinalize(),
 373                 this._hash
 374         },
 375         clone: function () {
 376             var a = k.clone.call(this);
 377             return a._hash = this._hash.clone(),
 378                 a
 379         },
 380         blockSize: 16,
 381         _createHelper: function (a) {
 382             return function (e, c) {
 383                 return a.create(c).finalize(e)
 384             }
 385         },
 386         _createHmacHelper: function (a) {
 387             return function (e, c) {
 388                 return d.HMAC.create(a, c).finalize(e)
 389             }
 390         }
 391     });
 392     var d = m.algo = {};
 393     return m
 394 }(Math);
 395 (function () {
 396         var a = CryptoJS
 397             , b = a.lib.WordArray;
 398         a.enc.Base64 = {
 399             stringify: function (c) {
 400                 var k = c.words
 401                     , f = c.sigBytes
 402                     , h = this._map;
 403                 c.clamp();
 404                 for (var c = [], d = 0; d >> 2] >>> 24 - 8 * (d % 4) & 255) <>> 2] >>> 24 - 8 * ((d + 1) % 4) & 255) <>> 2] >>> 24 - 8 * ((d + 2) % 4) & 255, g = 0; 4 > g && d + 0.75 * g >> 6 * (3 - g) & 63))
 407                     }
 408                 }
 409                 if (k = h.charAt(64)) {
 410                     for (; c.length % 4;) {
 411                         c.push(k)
 412                     }
 413                 }
 414                 return c.join("")
 415             },
 416             parse: function (d) {
 417                 var d = d.replace(/\s/g, "")
 418                     , h = d.length
 419                     , j = this._map
 420                     , k = j.charAt(64);
 421                 k && (k = d.indexOf(k),
 422                 -1 != k && (h = k));
 423                 for (var k = [], i = 0, l = 0; l < h; l++) {
 424                     if (l % 4) {
 425                         var c = j.indexOf(d.charAt(l - 1)) <>> 6 - 2 * (l % 4);
 427                         k[i >>> 2] |= (c | g) << 24 - 8 * (i % 4),
 428                             i++
 429                     }
 430                 }
 431                 return b.create(k, i)
 432             },
 433             _map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
 434         }
 435     }
 436 )(),
 437     function (c) {
 438         function m(a, x, q, v, f, w, u) {
 439             return a = a + (x & q | ~x & v) + f + u,
 440             (a <>> 32 - w) + x
 441         }
 442 
 443         function h(a, x, q, v, f, w, u) {
 444             return a = a + (x & v | q & ~v) + f + u,
 445             (a <>> 32 - w) + x
 446         }
 447 
 448         function k(a, x, q, v, f, w, u) {
 449             return a = a + (x ^ q ^ v) + f + u,
 450             (a <>> 32 - w) + x
 451         }
 452 
 453         function g(a, x, q, v, f, w, u) {
 454             return a = a + (q ^ (x | ~v)) + f + u,
 455             (a <>> 32 - w) + x
 456         }
 457 
 458         var l = CryptoJS
 459             , j = l.lib
 460             , p = j.WordArray
 461             , j = j.Hasher
 462             , b = l.algo
 463             , d = [];
 464         (function () {
 465                 for (var a = 0; 64 > a; a++) {
 466                     d[a] = 4294967296 * c.abs(c.sin(a + 1)) | 0
 467                 }
 468             }
 469         )(),
 470             b = b.MD5 = j.extend({
 471                 _doReset: function () {
 472                     this._hash = p.create([1732584193, 4023233417, 2562383102, 271733878])
 473                 },
 474                 _doProcessBlock: function (q, v) {
 475                     for (var t = 0; 16 > t; t++) {
 476                         var w = v + t
 477                             , f = q[w];
 478                         q[w] = (f <>> 24) & 16711935 | (f <>> 8) & 4278255360
 479                     }
 480                     for (var w = this._hash.words, f = w[0], r = w[1], i = w[2], n = w[3], t = 0; 64 > t; t += 4) {
 481                         16 > t ? (f = m(f, r, i, n, q[v + t], 7, d[t]),
 482                             n = m(n, f, r, i, q[v + t + 1], 12, d[t + 1]),
 483                             i = m(i, n, f, r, q[v + t + 2], 17, d[t + 2]),
 484                             r = m(r, i, n, f, q[v + t + 3], 22, d[t + 3])) : 32 > t ? (f = h(f, r, i, n, q[v + (t + 1) % 16], 5, d[t]),
 485                             n = h(n, f, r, i, q[v + (t + 6) % 16], 9, d[t + 1]),
 486                             i = h(i, n, f, r, q[v + (t + 11) % 16], 14, d[t + 2]),
 487                             r = h(r, i, n, f, q[v + t % 16], 20, d[t + 3])) : 48 > t ? (f = k(f, r, i, n, q[v + (3 * t + 5) % 16], 4, d[t]),
 488                             n = k(n, f, r, i, q[v + (3 * t + 8) % 16], 11, d[t + 1]),
 489                             i = k(i, n, f, r, q[v + (3 * t + 11) % 16], 16, d[t + 2]),
 490                             r = k(r, i, n, f, q[v + (3 * t + 14) % 16], 23, d[t + 3])) : (f = g(f, r, i, n, q[v + 3 * t % 16], 6, d[t]),
 491                             n = g(n, f, r, i, q[v + (3 * t + 7) % 16], 10, d[t + 1]),
 492                             i = g(i, n, f, r, q[v + (3 * t + 14) % 16], 15, d[t + 2]),
 493                             r = g(r, i, n, f, q[v + (3 * t + 5) % 16], 21, d[t + 3]))
 494                     }
 495                     w[0] = w[0] + f | 0,
 496                         w[1] = w[1] + r | 0,
 497                         w[2] = w[2] + i | 0,
 498                         w[3] = w[3] + n | 0
 499                 },
 500                 _doFinalize: function () {
 501                     var a = this._data
 502                         , o = a.words
 503                         , f = 8 * this._nDataBytes
 504                         , i = 8 * a.sigBytes;
 505                     o[i >>> 5] |= 128 <>> 9 << 4) + 14] = (f <>> 24) & 16711935 | (f <>> 8) & 4278255360,
 507                         a.sigBytes = 4 * (o.length + 1),
 508                         this._process(),
 509                         a = this._hash.words;
 510                     for (o = 0; 4 > o; o++) {
 511                         f = a[o],
 512                             a[o] = (f <>> 24) & 16711935 | (f <>> 8) & 4278255360
 513                     }
 514                 }
 515             }),
 516             l.MD5 = j._createHelper(b),
 517             l.HmacMD5 = j._createHmacHelper(b)
 518     }(Math),
 519     function () {
 520         var a = CryptoJS
 521             , f = a.lib
 522             , c = f.Base
 523             , d = f.WordArray
 524             , f = a.algo
 525             , b = f.EvpKDF = c.extend({
 526             cfg: c.extend({
 527                 keySize: 4,
 528                 hasher: f.MD5,
 529                 iterations: 1
 530             }),
 531             init: function (g) {
 532                 this.cfg = this.cfg.extend(g)
 533             },
 534             compute: function (h, q) {
 535                 for (var l = this.cfg, k = l.hasher.create(), p = d.create(), m = p.words, r = l.keySize, l = l.iterations; m.length < r;) {
 536                     g && k.update(g);
 537                     var g = k.update(h).finalize(q);
 538                     k.reset();
 539                     for (var j = 1; j < l; j++) {
 540                         g = k.finalize(g),
 541                             k.reset()
 542                     }
 543                     p.concat(g)
 544                 }
 545                 return p.sigBytes = 4 * r,
 546                     p
 547             }
 548         });
 549         a.EvpKDF = function (g, i, h) {
 550             return b.create(h).compute(g, i)
 551         }
 552     }(),
 553 CryptoJS.lib.Cipher || function (k) {
 554     var C = CryptoJS
 555         , x = C.lib
 556         , A = x.Base
 557         , v = x.WordArray
 558         , B = x.BufferedBlockAlgorithm
 559         , y = C.enc.Base64
 560         , D = C.algo.EvpKDF
 561         , b = x.Cipher = B.extend({
 562         cfg: A.extend(),
 563         createEncryptor: function (a, c) {
 564             return this.create(this._ENC_XFORM_MODE, a, c)
 565         },
 566         createDecryptor: function (a, c) {
 567             return this.create(this._DEC_XFORM_MODE, a, c)
 568         },
 569         init: function (a, d, c) {
 570             this.cfg = this.cfg.extend(c),
 571                 this._xformMode = a,
 572                 this._key = d,
 573                 this.reset()
 574         },
 575         reset: function () {
 576             B.reset.call(this),
 577                 this._doReset()
 578         },
 579         process: function (a) {
 580             return this._append(a),
 581                 this._process()
 582         },
 583         finalize: function (a) {
 584             return a && this._append(a),
 585                 this._doFinalize()
 586         },
 587         keySize: 4,
 588         ivSize: 4,
 589         _ENC_XFORM_MODE: 1,
 590         _DEC_XFORM_MODE: 2,
 591         _createHelper: function () {
 592             return function (a) {
 593                 return {
 594                     encrypt: function (e, c, d) {
 595                         return ("string" == typeof c ? j : z).encrypt(a, e, c, d)
 596                     },
 597                     decrypt: function (e, c, d) {
 598                         return ("string" == typeof c ? j : z).decrypt(a, e, c, d)
 599                     }
 600                 }
 601             }
 602         }()
 603     });
 604     x.StreamCipher = b.extend({
 605         _doFinalize: function () {
 606             return this._process(!0)
 607         },
 608         blockSize: 1
 609     });
 610     var m = C.mode = {}
 611         , w = x.BlockCipherMode = A.extend({
 612         createEncryptor: function (a, c) {
 613             return this.Encryptor.create(a, c)
 614         },
 615         createDecryptor: function (a, c) {
 616             return this.Decryptor.create(a, c)
 617         },
 618         init: function (a, c) {
 619             this._cipher = a,
 620                 this._iv = c
 621         }
 622     })
 623         , m = m.CBC = function () {
 624         function c(l, e, f) {
 625             var d = this._iv;
 626             d ? this._iv = k : d = this._prevBlock;
 627             for (var h = 0; h < f; h++) {
 628                 l[e + h] ^= d[h]
 629             }
 630         }
 631 
 632         var a = w.extend();
 633         return a.Encryptor = a.extend({
 634             processBlock: function (d, h) {
 635                 var l = this._cipher
 636                     , f = l.blockSize;
 637                 c.call(this, d, h, f),
 638                     l.encryptBlock(d, h),
 639                     this._prevBlock = d.slice(h, h + f)
 640             }
 641         }),
 642             a.Decryptor = a.extend({
 643                 processBlock: function (d, h) {
 644                     var l = this._cipher
 645                         , f = l.blockSize
 646                         , o = d.slice(h, h + f);
 647                     l.decryptBlock(d, h),
 648                         c.call(this, d, h, f),
 649                         this._prevBlock = o
 650                 }
 651             }),
 652             a
 653     }()
 654         , g = (C.pad = {}).Pkcs7 = {
 655         pad: function (a, i) {
 656             for (var c = 4 * i, c = c - a.sigBytes % c, f = c << 24 | c << 16 | c << 8 | c, h = [], d = 0; d >> 2] & 255
 664         }
 665     };
 666     x.BlockCipher = b.extend({
 667         cfg: b.cfg.extend({
 668             mode: m,
 669             padding: g
 670         }),
 671         reset: function () {
 672             b.reset.call(this);
 673             var a = this.cfg
 674                 , d = a.iv
 675                 , a = a.mode;
 676             if (this._xformMode == this._ENC_XFORM_MODE) {
 677                 var c = a.createEncryptor
 678             } else {
 679                 c = a.createDecryptor,
 680                     this._minBufferSize = 1
 681             }
 682             this._mode = c.call(a, this, d && d.words)
 683         },
 684         _doProcessBlock: function (a, c) {
 685             this._mode.processBlock(a, c)
 686         },
 687         _doFinalize: function () {
 688             var a = this.cfg.padding;
 689             if (this._xformMode == this._ENC_XFORM_MODE) {
 690                 a.pad(this._data, this.blockSize);
 691                 var c = this._process(!0)
 692             } else {
 693                 c = this._process(!0),
 694                     a.unpad(c)
 695             }
 696             return c
 697         },
 698         blockSize: 4
 699     });
 700     var q = x.CipherParams = A.extend({
 701         init: function (a) {
 702             this.mixIn(a)
 703         },
 704         toString: function (a) {
 705             return (a || this.formatter).stringify(this)
 706         }
 707     })
 708         , m = (C.format = {}).OpenSSL = {
 709         stringify: function (a) {
 710             var c = a.ciphertext
 711                 , a = a.salt
 712                 , c = (a ? v.create([1398893684, 1701076831]).concat(a).concat(c) : c).toString(y);
 713             return c = c.replace(/(.{64})/g, "$1\n")
 714         },
 715         parse: function (a) {
 716             var a = y.parse(a)
 717                 , d = a.words;
 718             if (1398893684 == d[0] && 1701076831 == d[1]) {
 719                 var c = v.create(d.slice(2, 4));
 720                 d.splice(0, 4),
 721                     a.sigBytes -= 16
 722             }
 723             return q.create({
 724                 ciphertext: a,
 725                 salt: c
 726             })
 727         }
 728     }
 729         , z = x.SerializableCipher = A.extend({
 730         cfg: A.extend({
 731             format: m
 732         }),
 733         encrypt: function (a, h, d, f) {
 734             var f = this.cfg.extend(f)
 735                 , c = a.createEncryptor(d, f)
 736                 , h = c.finalize(h)
 737                 , c = c.cfg;
 738             return q.create({
 739                 ciphertext: h,
 740                 key: d,
 741                 iv: c.iv,
 742                 algorithm: a,
 743                 mode: c.mode,
 744                 padding: c.padding,
 745                 blockSize: a.blockSize,
 746                 formatter: f.format
 747             })
 748         },
 749         decrypt: function (a, f, c, d) {
 750             return d = this.cfg.extend(d),
 751                 f = this._parse(f, d.format),
 752                 a.createDecryptor(c, d).finalize(f.ciphertext)
 753         },
 754         _parse: function (a, c) {
 755             return "string" == typeof a ? c.parse(a) : a
 756         }
 757     })
 758         , C = (C.kdf = {}).OpenSSL = {
 759         compute: function (a, f, c, d) {
 760             return d || (d = v.random(8)),
 761                 a = D.create({
 762                     keySize: f + c
 763                 }).compute(a, d),
 764                 c = v.create(a.words.slice(f), 4 * c),
 765                 a.sigBytes = 4 * f,
 766                 q.create({
 767                     key: a,
 768                     iv: c,
 769                     salt: d
 770                 })
 771         }
 772     }
 773         , j = x.PasswordBasedCipher = z.extend({
 774         cfg: z.cfg.extend({
 775             kdf: C
 776         }),
 777         encrypt: function (a, f, c, d) {
 778             return d = this.cfg.extend(d),
 779                 c = d.kdf.compute(c, a.keySize, a.ivSize),
 780                 d.iv = c.iv,
 781                 a = z.encrypt.call(this, a, f, c.key, d),
 782                 a.mixIn(c),
 783                 a
 784         },
 785         decrypt: function (a, f, c, d) {
 786             return d = this.cfg.extend(d),
 787                 f = this._parse(f, d.format),
 788                 c = d.kdf.compute(c, a.keySize, a.ivSize, f.salt),
 789                 d.iv = c.iv,
 790                 z.decrypt.call(this, a, f, c.key, d)
 791         }
 792     })
 793 }(),
 794     function () {
 795         function g(a, f) {
 796             var c = (this._lBlock >>> a ^ this._rBlock) & f;
 797             this._rBlock ^= c,
 798                 this._lBlock ^= c <>> a ^ this._lBlock) & f;
 803             this._lBlock ^= c,
 804                 this._rBlock ^= c < f; f++) {
1342                         var l = p[f] - 1;
1343                         u[f] = a[l >>> 5] >>> 31 - l % 32 & 1
1344                     }
1345                     a = this._subKeys = [];
1346                     for (l = 0; 16 > l; l++) {
1347                         for (var c = a[l] = [], o = b[l], f = 0; 24 > f; f++) {
1348                             c[f / 6 | 0] |= u[(x[f] - 1 + o) % 28] << 31 - f % 6,
1349                                 c[4 + (f / 6 | 0)] |= u[28 + (x[f + 24] - 1 + o) % 28] << 31 - f % 6
1350                         }
1351                         c[0] = c[0] <>> 31;
1352                         for (f = 1; 7 > f; f++) {
1353                             c[f] >>>= 4 * (f - 1) + 3
1354                         }
1355                         c[7] = c[7] <>> 27
1356                     }
1357                     u = this._invSubKeys = [];
1358                     for (f = 0; 16 > f; f++) {
1359                         u[f] = a[15 - f]
1360                     }
1361                 },
1362                 encryptBlock: function (a, c) {
1363                     this._doCryptBlock(a, c, this._subKeys)
1364                 },
1365                 decryptBlock: function (a, c) {
1366                     this._doCryptBlock(a, c, this._invSubKeys)
1367                 },
1368                 _doCryptBlock: function (y, A, t) {
1369                     this._lBlock = y[A],
1370                         this._rBlock = y[A + 1],
1371                         g.call(this, 4, 252645135),
1372                         g.call(this, 16, 65535),
1373                         w.call(this, 2, 858993459),
1374                         w.call(this, 8, 16711935),
1375                         g.call(this, 1, 1431655765);
1376                     for (var B = 0; 16 > B; B++) {
1377                         for (var z = t[B], C = this._lBlock, e = this._rBlock, f = 0, l = 0; 8 > l; l++) {
1378                             f |= h[l][((e ^ z[l]) & k[l]) >>> 0]
1379                         }
1380                         this._lBlock = e,
1381                             this._rBlock = C ^ f
1382                     }
1383                     t = this._lBlock,
1384                         this._lBlock = this._rBlock,
1385                         this._rBlock = t,
1386                         g.call(this, 1, 1431655765),
1387                         w.call(this, 8, 16711935),
1388                         w.call(this, 2, 858993459),
1389                         g.call(this, 16, 65535),
1390                         g.call(this, 4, 252645135),
1391                         y[A] = this._lBlock,
1392                         y[A + 1] = this._rBlock
1393                 },
1394                 keySize: 2,
1395                 ivSize: 2,
1396                 blockSize: 2
1397             });
1398         m.DES = q._createHelper(d),
1399             v = v.TripleDES = q.extend({
1400                 _doReset: function () {
1401                     var a = this._key.words;
1402                     this._des1 = d.createEncryptor(j.create(a.slice(0, 2))),
1403                         this._des2 = d.createEncryptor(j.create(a.slice(2, 4))),
1404                         this._des3 = d.createEncryptor(j.create(a.slice(4, 6)))
1405                 },
1406                 encryptBlock: function (a, c) {
1407                     this._des1.encryptBlock(a, c),
1408                         this._des2.decryptBlock(a, c),
1409                         this._des3.encryptBlock(a, c)
1410                 },
1411                 decryptBlock: function (a, c) {
1412                     this._des3.decryptBlock(a, c),
1413                         this._des2.encryptBlock(a, c),
1414                         this._des1.decryptBlock(a, c)
1415                 },
1416                 keySize: 6,
1417                 ivSize: 2,
1418                 blockSize: 2
1419             }),
1420             m.TripleDES = q._createHelper(v)
1421     }();
1422 CryptoJS.mode.ECB = function () {
1423     var a = CryptoJS.lib.BlockCipherMode.extend();
1424     return a.Encryptor = a.extend({
1425         processBlock: function (b, c) {
1426             this._cipher.encryptBlock(b, c)
1427         }
1428     }),
1429     a.Decryptor = a.extend({
1430         processBlock: function (b, c) {
1431             this._cipher.decryptBlock(b, c)
1432         }
1433     }),
1434     a
1435 }();

View Code

得到了加密代码之后,我们只需要使用 execjs 进行编译和调用就可以了,使用方法可以参考上一篇博客。

三、模拟登录

通过前面的步骤,我们已经能够得到登录所需要的参数了,编写好加密方法之后,可以使用 Postman 进行测试,下面是用 Postman 进行登录的 POST 请求的响应结果:

从图中可以看到,返回的是一个 JSON 文件,其中包含了登录请求是否成功、登录的结果信息和用户信息等内容。 下面就是使用 Python 编写的模拟登录时光网的代码:

 1 """
 2 Version: Python3.7
 3 Author: OniOn
 4 Site: http://www.cnblogs.com/TM0831/
 5 Time: 2020/7/5 14:19
 6 """
 7 import execjs
 8 import requests
 9 
10 
11 class MTimeSpider:
12     def __init__(self, username, password):
13         self.username = username
14         self.password = password
15 
16     def encrypted(self):
17         """
18         use JavaScript to encrypt the password
19         :return:
20         """
21         with open("encrypt.js", "r", encoding="utf-8") as f:
22             ctx = execjs.compile(f.read())
23             self.password = ctx.call("encrypt", self.password)
24 
25     def request(self):
26         """
27         send request and get the response
28         :return:
29         """
30         self.encrypted()
31         login_api = "https://m.mtime.cn/Service/callback-comm.mi/user/login.api"
32         data = {
33             "t": "20207515574379774",
34             "name": self.username,
35             "password": self.password,
36             "code": "",
37             "codeId": ""
38         }
39         res = requests.post(url=login_api, data=data)
40         status, msg = res.json()["data"]["status"], res.json()["data"]["msg"]
41         # print(status, msg)
42         if status == 1:
43             name = res.json()["data"]["user"]["nickname"]
44             print("用户: {} 登录成功!".format(name))
45         else:
46             print("登录失败!{}".format(msg))
47 
48 
49 if __name__ == '__main__':
50     print("请输入账号:")
51     usr = input()
52     print("请输入密码:")
53     pwd = input()
54     spider = MTimeSpider(usr, pwd)
55     spider.request()

运行后的截图如下:

完整代码已上传到 GitHub