本文主要是介绍中国观鸟记录中心 birdreport 爬虫逆向加密 AES解密分析和代码 2023版,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
1 基本分析3步走
请求头中需要破解Requestid 以及 Sign
载荷的Form表单是一个加密字符串
相应的数据是一个加密数据需要破解
2 加密逻辑分析
2.1 分析timestamp requestId sign
2.2 分析表单加密参数
3 解密相应数据
4 完整代码
1 基本分析3步走
请求头中需要破解Requestid 以及 Sign
载荷的Form表单是一个加密字符串
相应的数据是一个加密数据需要破解
2 加密逻辑分析
2.1 分析timestamp requestId sign
我们可以通过XHR断点调试,经过分析可以定位到在魔改后的Jquery.js里面 在k.beforeSend 是调用了加密逻辑
我们进入beforeSend函数
在beforeSend 函数里面我们看到最下面设置了头部的三个参数timestamp requestId sign
a.setRequestHeader("timestamp", c);
a.setRequestHeader('requestId', d);
a.setRequestHeader('sign', f)
在往上看
var c = Date.parse(new Date()); //是个时间戳
var d = getUuid(); //getUuid 是一个函数返回一个Uuid可以固定
var e = JSON.stringify(sort_ASCII(dataTojson(b.data || '{}'))) //b.data进行处理我们可以看下b.data和e 此处的b.data 会根据搜索条件的不同会略有区别
我们的sign即我们的f 是一个MD5加密(e + d + c)
var f = MD5(e + d + c);
这个MD5函数可以在jqueryAjax.js直接扣到
2.2 分析表单加密参数
接下来分析表单加密数据
可以看到此处调用了一个加密方法encrypt.encryptUnicodeLong(e);
我们进入对应的函数文件只要扣对应的标注函数即可,标注函数前面的代码没用主要用来环境检测
我们可以把这个函数自己命名下比如我这里命名为forever,此外我们需要补环境window 和 navigator
由于代码太长,请看最终的完整代码
执行结果,这样我们就获取到了需要发送的加密form表单数据
3 解密相应数据
返回的数据我们还是可以通过XHR断点方式定位到
这里调用了a.parseData
进入a.parseData方法可以看到又调用了BIRDREPORT_APIJS.decode,并且传入了返回的加密数据
进入加密方法 可以看到这个是AES加密
在js文件的头部可以看到key iv是固定的
我们可以封装解密函数
4 完整代码
最后完整的代码包含加密解密 以及axios发送请求
JSEncrypt = require('jsencrypt')
axios = require('axios')
var CryptoJS = require('crypto-js')
window = global
navigator = {appName: 'Netscape'
}
function forever () {'use strict';var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";function int2char(n) {return BI_RM.charAt(n);}//#region BIT_OPERATIONS
// (public) this & afunction op_and(x, y) {return x & y;}// (public) this | afunction op_or(x, y) {return x | y;}// (public) this ^ afunction op_xor(x, y) {return x ^ y;}// (public) this & ~afunction op_andnot(x, y) {return x & ~y;}// return index of lowest 1-bit in x, x < 2^31function lbit(x) {if (x == 0) {return -1;}var r = 0;if ((x & 0xffff) == 0) {x >>= 16;r += 16;}if ((x & 0xff) == 0) {x >>= 8;r += 8;}if ((x & 0xf) == 0) {x >>= 4;r += 4;}if ((x & 3) == 0) {x >>= 2;r += 2;}if ((x & 1) == 0) {++r;}return r;}// return number of 1 bits in xfunction cbit(x) {var r = 0;while (x != 0) {x &= x - 1;++r;}return r;}//#endregion BIT_OPERATIONSvar b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var b64pad = "=";function hex2b64(h) {var i;var c;var ret = "";for (i = 0; i + 3 <= h.length; i += 3) {c = parseInt(h.substring(i, i + 3), 16);ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);}if (i + 1 == h.length) {c = parseInt(h.substring(i, i + 1), 16);ret += b64map.charAt(c << 2);}else if (i + 2 == h.length) {c = parseInt(h.substring(i, i + 2), 16);ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);}while ((ret.length & 3) > 0) {ret += b64pad;}return ret;}// convert a base64 string to hexfunction b64tohex(s) {var ret = "";var i;var k = 0; // b64 state, 0-3var slop = 0;for (i = 0; i < s.length; ++i) {if (s.charAt(i) == b64pad) {break;}var v = b64map.indexOf(s.charAt(i));if (v < 0) {continue;}if (k == 0) {ret += int2char(v >> 2);slop = v & 3;k = 1;}else if (k == 1) {ret += int2char((slop << 2) | (v >> 4));slop = v & 0xf;k = 2;}else if (k == 2) {ret += int2char(slop);ret += int2char(v >> 2);slop = v & 3;k = 3;}else {ret += int2char((slop << 2) | (v >> 4));ret += int2char(v & 0xf);k = 0;}}if (k == 1) {ret += int2char(slop << 2);}return ret;}/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** *//* global Reflect, Promise */var extendStatics = Object.setPrototypeOf ||({__proto__: []} instanceof Array && function (d, b) {d.__proto__ = b;}) ||function (d, b) {for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];};function __extends(d, b) {extendStatics(d, b);function __() {this.constructor = d;}d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());}// Hex JavaScript decoder
// Copyright (c) 2008-2013 Lapo Luchini <lapo@lapo.it>
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE./*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */var decoder;var Hex = {decode: function (a) {var i;if (decoder === undefined) {var hex = "0123456789ABCDEF";var ignore = " \f\n\r\t\u00A0\u2028\u2029";decoder = {};for (i = 0; i < 16; ++i) {decoder[hex.charAt(i)] = i;}hex = hex.toLowerCase();for (i = 10; i < 16; ++i) {decoder[hex.charAt(i)] = i;}for (i = 0; i < ignore.length; ++i) {decoder[ignore.charAt(i)] = -1;}}var out = [];var bits = 0;var char_count = 0;for (i = 0; i < a.length; ++i) {var c = a.charAt(i);if (c == "=") {break;}c = decoder[c];if (c == -1) {continue;}if (c === undefined) {throw new Error("Illegal character at offset " + i);}bits |= c;if (++char_count >= 2) {out[out.length] = bits;bits = 0;char_count = 0;}else {bits <<= 4;}}if (char_count) {throw new Error("Hex encoding incomplete: 4 bits missing");}return out;}};// Base64 JavaScript decoder
// Copyright (c) 2008-2013 Lapo Luchini <lapo@lapo.it>
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE./*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */var decoder$1;var Base64 = {decode: function (a) {var i;if (decoder$1 === undefined) {var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var ignore = "= \f\n\r\t\u00A0\u2028\u2029";decoder$1 = Object.create(null);for (i = 0; i < 64; ++i) {decoder$1[b64.charAt(i)] = i;}for (i = 0; i < ignore.length; ++i) {decoder$1[ignore.charAt(i)] = -1;}}var out = [];var bits = 0;var char_count = 0;for (i = 0; i < a.length; ++i) {var c = a.charAt(i);if (c == "=") {break;}c = decoder$1[c];if (c == -1) {continue;}if (c === undefined) {throw new Error("Illegal character at offset " + i);}bits |= c;if (++char_count >= 4) {out[out.length] = (bits >> 16);out[out.length] = (bits >> 8) & 0xFF;out[out.length] = bits & 0xFF;bits = 0;char_count = 0;}else {bits <<= 6;}}switch (char_count) {case 1:throw new Error("Base64 encoding incomplete: at least 2 bits missing");case 2:out[out.length] = (bits >> 10);break;case 3:out[out.length] = (bits >> 16);out[out.length] = (bits >> 8) & 0xFF;break;}return out;},re: /-----BEGIN [^-]+-----([A-Za-z0-9+\/=\s]+)-----END [^-]+-----|begin-base64[^\n]+\n([A-Za-z0-9+\/=\s]+)====/,unarmor: function (a) {var m = Base64.re.exec(a);if (m) {if (m[1]) {a = m[1];}else if (m[2]) {a = m[2];}else {throw new Error("RegExp out of sync");}}return Base64.decode(a);}};// Big integer base-10 printing library
// Copyright (c) 2014 Lapo Luchini <lapo@lapo.it>
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE./*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */var max = 10000000000000; // biggest integer that can still fit 2^53 when multiplied by 256var Int10 = /** @class */ (function () {function Int10(value) {this.buf = [+value || 0];}Int10.prototype.mulAdd = function (m, c) {// assert(m <= 256)var b = this.buf;var l = b.length;var i;var t;for (i = 0; i < l; ++i) {t = b[i] * m + c;if (t < max) {c = 0;}else {c = 0 | (t / max);t -= c * max;}b[i] = t;}if (c > 0) {b[i] = c;}};Int10.prototype.sub = function (c) {// assert(m <= 256)var b = this.buf;var l = b.length;var i;var t;for (i = 0; i < l; ++i) {t = b[i] - c;if (t < 0) {t += max;c = 1;}else {c = 0;}b[i] = t;}while (b[b.length - 1] === 0) {b.pop();}};Int10.prototype.toString = function (base) {if ((base || 10) != 10) {throw new Error("only base 10 is supported");}var b = this.buf;var s = b[b.length - 1].toString();for (var i = b.length - 2; i >= 0; --i) {s += (max + b[i]).toString().substring(1);}return s;};Int10.prototype.valueOf = function () {var b = this.buf;var v = 0;for (var i = b.length - 1; i >= 0; --i) {v = v * max + b[i];}return v;};Int10.prototype.simplify = function () {var b = this.buf;return (b.length == 1) ? b[0] : this;};return Int10;}());// ASN.1 JavaScript decodervar ellipsis = "\u2026";var reTimeS = /^(\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/;var reTimeL = /^(\d\d\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/;function stringCut(str, len) {if (str.length > len) {str = str.substring(0, len) + ellipsis;}return str;}var Stream = /** @class */ (function () {function Stream(enc, pos) {this.hexDigits = "0123456789ABCDEF";if (enc instanceof Stream) {this.enc = enc.enc;this.pos = enc.pos;}else {// enc should be an array or a binary stringthis.enc = enc;this.pos = pos;}}Stream.prototype.get = function (pos) {if (pos === undefined) {pos = this.pos++;}if (pos >= this.enc.length) {throw new Error("Requesting byte offset " + pos + " on a stream of length " + this.enc.length);}return ("string" === typeof this.enc) ? this.enc.charCodeAt(pos) : this.enc[pos];};Stream.prototype.hexByte = function (b) {return this.hexDigits.charAt((b >> 4) & 0xF) + this.hexDigits.charAt(b & 0xF);};Stream.prototype.hexDump = function (start, end, raw) {var s = "";for (var i = start; i < end; ++i) {s += this.hexByte(this.get(i));if (raw !== true) {switch (i & 0xF) {case 0x7:s += " ";break;case 0xF:s += "\n";break;default:s += " ";}}}return s;};Stream.prototype.isASCII = function (start, end) {for (var i = start; i < end; ++i) {var c = this.get(i);if (c < 32 || c > 176) {return false;}}return true;};Stream.prototype.parseStringISO = function (start, end) {var s = "";for (var i = start; i < end; ++i) {s += String.fromCharCode(this.get(i));}return s;};Stream.prototype.parseStringUTF = function (start, end) {var s = "";for (var i = start; i < end;) {var c = this.get(i++);if (c < 128) {s += String.fromCharCode(c);}else if ((c > 191) && (c < 224)) {s += String.fromCharCode(((c & 0x1F) << 6) | (this.get(i++) & 0x3F));}else {s += String.fromCharCode(((c & 0x0F) << 12) | ((this.get(i++) & 0x3F) << 6) | (this.get(i++) & 0x3F));}}return s;};Stream.prototype.parseStringBMP = function (start, end) {var str = "";var hi;var lo;for (var i = start; i < end;) {hi = this.get(i++);lo = this.get(i++);str += String.fromCharCode((hi << 8) | lo);}return str;};Stream.prototype.parseTime = function (start, end, shortYear) {var s = this.parseStringISO(start, end);var m = (shortYear ? reTimeS : reTimeL).exec(s);if (!m) {return "Unrecognized time: " + s;}if (shortYear) {// to avoid querying the timer, use the fixed range [1970, 2069]// it will conform with ITU X.400 [-10, +40] sliding window until 2030m[1] = +m[1];m[1] += (+m[1] < 70) ? 2000 : 1900;}s = m[1] + "-" + m[2] + "-" + m[3] + " " + m[4];if (m[5]) {s += ":" + m[5];if (m[6]) {s += ":" + m[6];if (m[7]) {s += "." + m[7];}}}if (m[8]) {s += " UTC";if (m[8] != "Z") {s += m[8];if (m[9]) {s += ":" + m[9];}}}return s;};Stream.prototype.parseInteger = function (start, end) {var v = this.get(start);var neg = (v > 127);var pad = neg ? 255 : 0;var len;var s = "";// skip unuseful bits (not allowed in DER)while (v == pad && ++start < end) {v = this.get(start);}len = end - start;if (len === 0) {return neg ? -1 : 0;}// show bit length of huge integersif (len > 4) {s = v;len <<= 3;while (((+s ^ pad) & 0x80) == 0) {s = +s << 1;--len;}s = "(" + len + " bit)\n";}// decode the integerif (neg) {v = v - 256;}var n = new Int10(v);for (var i = start + 1; i < end; ++i) {n.mulAdd(256, this.get(i));}return s + n.toString();};Stream.prototype.parseBitString = function (start, end, maxLength) {var unusedBit = this.get(start);var lenBit = ((end - start - 1) << 3) - unusedBit;var intro = "(" + lenBit + " bit)\n";var s = "";for (var i = start + 1; i < end; ++i) {var b = this.get(i);var skip = (i == end - 1) ? unusedBit : 0;for (var j = 7; j >= skip; --j) {s += (b >> j) & 1 ? "1" : "0";}if (s.length > maxLength) {return intro + stringCut(s, maxLength);}}return intro + s;};Stream.prototype.parseOctetString = function (start, end, maxLength) {if (this.isASCII(start, end)) {return stringCut(this.parseStringISO(start, end), maxLength);}var len = end - start;var s = "(" + len + " byte)\n";maxLength /= 2; // we work in bytesif (len > maxLength) {end = start + maxLength;}for (var i = start; i < end; ++i) {s += this.hexByte(this.get(i));}if (len > maxLength) {s += ellipsis;}return s;};Stream.prototype.parseOID = function (start, end, maxLength) {var s = "";var n = new Int10();var bits = 0;for (var i = start; i < end; ++i) {var v = this.get(i);n.mulAdd(128, v & 0x7F);bits += 7;if (!(v & 0x80)) {if (s === "") {n = n.simplify();if (n instanceof Int10) {n.sub(80);s = "2." + n.toString();}else {var m = n < 80 ? n < 40 ? 0 : 1 : 2;s = m + "." + (n - m * 40);}}else {s += "." + n.toString();}if (s.length > maxLength) {return stringCut(s, maxLength);}n = new Int10();bits = 0;}}if (bits > 0) {s += ".incomplete";}return s;};return Stream;}());var ASN1 = /** @class */ (function () {function ASN1(stream, header, length, tag, sub) {if (!(tag instanceof ASN1Tag)) {throw new Error("Invalid tag value.");}this.stream = stream;this.header = header;this.length = length;this.tag = tag;this.sub = sub;}ASN1.prototype.typeName = function () {switch (this.tag.tagClass) {case 0:// universalswitch (this.tag.tagNumber) {case 0x00:return "EOC";case 0x01:return "BOOLEAN";case 0x02:return "INTEGER";case 0x03:return "BIT_STRING";case 0x04:return "OCTET_STRING";case 0x05:return "NULL";case 0x06:return "OBJECT_IDENTIFIER";case 0x07:return "ObjectDescriptor";case 0x08:return "EXTERNAL";case 0x09:return "REAL";case 0x0A:return "ENUMERATED";case 0x0B:return "EMBEDDED_PDV";case 0x0C:return "UTF8String";case 0x10:return "SEQUENCE";case 0x11:return "SET";case 0x12:return "NumericString";case 0x13:return "PrintableString"; // ASCII subsetcase 0x14:return "TeletexString"; // aka T61Stringcase 0x15:return "VideotexString";case 0x16:return "IA5String"; // ASCIIcase 0x17:return "UTCTime";case 0x18:return "GeneralizedTime";case 0x19:return "GraphicString";case 0x1A:return "VisibleString"; // ASCII subsetcase 0x1B:return "GeneralString";case 0x1C:return "UniversalString";case 0x1E:return "BMPString";}return "Universal_" + this.tag.tagNumber.toString();case 1:return "Application_" + this.tag.tagNumber.toString();case 2:return "[" + this.tag.tagNumber.toString() + "]"; // Contextcase 3:return "Private_" + this.tag.tagNumber.toString();}};ASN1.prototype.content = function (maxLength) {if (this.tag === undefined) {return null;}if (maxLength === undefined) {maxLength = Infinity;}var content = this.posContent();var len = Math.abs(this.length);if (!this.tag.isUniversal()) {if (this.sub !== null) {return "(" + this.sub.length + " elem)";}return this.stream.parseOctetString(content, content + len, maxLength);}switch (this.tag.tagNumber) {case 0x01:// BOOLEANreturn (this.stream.get(content) === 0) ? "false" : "true";case 0x02:// INTEGERreturn this.stream.parseInteger(content, content + len);case 0x03:// BIT_STRINGreturn this.sub ? "(" + this.sub.length + " elem)" :this.stream.parseBitString(content, content + len, maxLength);case 0x04:// OCTET_STRINGreturn this.sub ? "(" + this.sub.length + " elem)" :this.stream.parseOctetString(content, content + len, maxLength);// case 0x05: // NULLcase 0x06:// OBJECT_IDENTIFIERreturn this.stream.parseOID(content, content + len, maxLength);// case 0x07: // ObjectDescriptor// case 0x08: // EXTERNAL// case 0x09: // REAL// case 0x0A: // ENUMERATED// case 0x0B: // EMBEDDED_PDVcase 0x10: // SEQUENCEcase 0x11:// SETif (this.sub !== null) {return "(" + this.sub.length + " elem)";}else {return "(no elem)";}case 0x0C:// UTF8Stringreturn stringCut(this.stream.parseStringUTF(content, content + len), maxLength);case 0x12: // NumericStringcase 0x13: // PrintableStringcase 0x14: // TeletexStringcase 0x15: // VideotexStringcase 0x16: // IA5String// case 0x19: // GraphicStringcase 0x1A:// VisibleString// case 0x1B: // GeneralString// case 0x1C: // UniversalStringreturn stringCut(this.stream.parseStringISO(content, content + len), maxLength);case 0x1E:// BMPStringreturn stringCut(this.stream.parseStringBMP(content, content + len), maxLength);case 0x17: // UTCTimecase 0x18:// GeneralizedTimereturn this.stream.parseTime(content, content + len, (this.tag.tagNumber == 0x17));}return null;};ASN1.prototype.toString = function () {return this.typeName() + "@" + this.stream.pos + "[header:" + this.header + ",length:" + this.length + ",sub:" + ((this.sub === null) ? "null" : this.sub.length) + "]";};ASN1.prototype.toPrettyString = function (indent) {if (indent === undefined) {indent = "";}var s = indent + this.typeName() + " @" + this.stream.pos;if (this.length >= 0) {s += "+";}s += this.length;if (this.tag.tagConstructed) {s += " (constructed)";}else if ((this.tag.isUniversal() && ((this.tag.tagNumber == 0x03) || (this.tag.tagNumber == 0x04))) && (this.sub !== null)) {s += " (encapsulates)";}s += "\n";if (this.sub !== null) {indent += " ";for (var i = 0, max = this.sub.length; i < max; ++i) {s += this.sub[i].toPrettyString(indent);}}return s;};ASN1.prototype.posStart = function () {return this.stream.pos;};ASN1.prototype.posContent = function () {return this.stream.pos + this.header;};ASN1.prototype.posEnd = function () {return this.stream.pos + this.header + Math.abs(this.length);};ASN1.prototype.toHexString = function () {return this.stream.hexDump(this.posStart(), this.posEnd(), true);};ASN1.decodeLength = function (stream) {var buf = stream.get();var len = buf & 0x7F;if (len == buf) {return len;}// no reason to use Int10, as it would be a huge buffer anywaysif (len > 6) {throw new Error("Length over 48 bits not supported at position " + (stream.pos - 1));}if (len === 0) {return null;} // undefinedbuf = 0;for (var i = 0; i < len; ++i) {buf = (buf * 256) + stream.get();}return buf;};/*** Retrieve the hexadecimal value (as a string) of the current ASN.1 element* @returns {string}* @public*/ASN1.prototype.getHexStringValue = function () {var hexString = this.toHexString();var offset = this.header * 2;var length = this.length * 2;return hexString.substr(offset, length);};ASN1.decode = function (str) {var stream;if (!(str instanceof Stream)) {stream = new Stream(str, 0);}else {stream = str;}var streamStart = new Stream(stream);var tag = new ASN1Tag(stream);var len = ASN1.decodeLength(stream);var start = stream.pos;var header = start - streamStart.pos;var sub = null;var getSub = function () {var ret = [];if (len !== null) {// definite lengthvar end = start + len;while (stream.pos < end) {ret[ret.length] = ASN1.decode(stream);}if (stream.pos != end) {throw new Error("Content size is not correct for container starting at offset " + start);}}else {// undefined lengthtry {for (; ;) {var s = ASN1.decode(stream);if (s.tag.isEOC()) {break;}ret[ret.length] = s;}len = start - stream.pos; // undefined lengths are represented as negative values}catch (e) {throw new Error("Exception while decoding undefined length content: " + e);}}return ret;};if (tag.tagConstructed) {// must have valid contentsub = getSub();}else if (tag.isUniversal() && ((tag.tagNumber == 0x03) || (tag.tagNumber == 0x04))) {// sometimes BitString and OctetString are used to encapsulate ASN.1try {if (tag.tagNumber == 0x03) {if (stream.get() != 0) {throw new Error("BIT STRINGs with unused bits cannot encapsulate.");}}sub = getSub();for (var i = 0; i < sub.length; ++i) {if (sub[i].tag.isEOC()) {throw new Error("EOC is not supposed to be actual content.");}}}catch (e) {// but silently ignore when they don'tsub = null;}}if (sub === null) {if (len === null) {throw new Error("We can't skip over an invalid tag with undefined length at offset " + start);}stream.pos = start + Math.abs(len);}return new ASN1(streamStart, header, len, tag, sub);};return ASN1;}());var ASN1Tag = /** @class */ (function () {function ASN1Tag(stream) {var buf = stream.get();this.tagClass = buf >> 6;this.tagConstructed = ((buf & 0x20) !== 0);this.tagNumber = buf & 0x1F;if (this.tagNumber == 0x1F) {var n = new Int10();do {buf = stream.get();n.mulAdd(128, buf & 0x7F);} while (buf & 0x80);this.tagNumber = n.simplify();}}ASN1Tag.prototype.isUniversal = function () {return this.tagClass === 0x00;};ASN1Tag.prototype.isEOC = function () {return this.tagClass === 0x00 && this.tagNumber === 0x00;};return ASN1Tag;}());// Copyright (c) 2005 Tom Wu
// Bits per digitvar dbits;
// JavaScript engine analysisvar canary = 0xdeadbeefcafe;var j_lm = ((canary & 0xffffff) == 0xefcafe);
//#regionvar lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997];var lplim = (1 << 26) / lowprimes[lowprimes.length - 1];
//#endregion
// (public) Constructorvar BigInteger = /** @class */ (function () {function BigInteger(a, b, c) {if (a != null) {if ("number" == typeof a) {this.fromNumber(a, b, c);}else if (b == null && "string" != typeof a) {this.fromString(a, 256);}else {this.fr
这篇关于中国观鸟记录中心 birdreport 爬虫逆向加密 AES解密分析和代码 2023版的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!