前言
同上一篇的aes加密一樣,也是偶然發現這個rsa加密的,目標網站我就不說了,保密。
當我發現這個網站是ajax加載時:
我已經習以為常,正在進行爬取時,發現返回為空,我開始用findler抓包,發現它驗證了cookie,然后我帶上cookie訪問放到headers里,就能得到結果
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36', 'Cookie': 'ASP.NET_SessionId=minwuelgy2ounvdyz3iy2por; Hm_lvt_db393520fa240b442a13a6d1c5ae95c1=1580346880; Hm_lvt_9d1de05cc99f08ddb5dc6d5e4d32ad30=1580346880; Hm_lvt_94bfa5b89a33cebfead2f88d38657023=1580346880; __root_domain_v=.fujian.gov.cn; _qddaz=QD.3g0yf8.g6u01n.k601qabh; _qdda=4-1.1o7qs8; _qddab=4-4srcpb.k601qagy; _qddamta_2852155767=4-0; _qddagsx_02095bad0b=ce61f2a659adb14f8a169b6f6e05c81a5ba0b7c10c14dab079ac59c11837474633c1cf8d45a58a941043e96faadd7e87a1ed7dd0a20cbc96ab5c957d44eab96abc9fb0317a0d72926ee0051947182f60999b701f7a8e1e7b41f74d9b54e46a352835f09034c3c7fd72247adcbf81fae7b154b077d24d4d17274167c1291cbe0d; Hm_lpvt_9d1de05cc99f08ddb5dc6d5e4d32ad30=1580346887; Hm_lpvt_94bfa5b89a33cebfead2f88d38657023=1580346887; Hm_lpvt_db393520fa240b442a13a6d1c5ae95c1=1580346887' }
這就完了嗎?還差得遠呢,而網上大部分對於這種cookie的爬蟲都是只到這一步就結束了,我當時查資料的時候也是給我整懵逼了,網上一搜基本都是如此,我不diss誰,我就想說,那如果爬蟲程序每天都要獲取呢,或者還可能需要在服務器上運行爬蟲程序呢?你難道每次運行的時候都用瀏覽器去訪問一次然后f12把cookie復制出來嗎?想想這樣繁瑣不?
有朋友會想,用requests的session對象保持會話啊,會自動帶上cookie的,這條路我試了,行不通,cookie只有【ASP.NET_SessionId
】,這個參數后面根據我的發現是可有可無,而且響應頭里的set-cookie也只設置了【ASP.NET_SessionId】,根本無效。還有的會想,請求一次之后把cookie保存下然后下次再帶上,這個方法其實跟用session對象是一個方式,所以也行不通
無效的原因在本文下面已說到,驗證的是下面那個參數。
因為都知道,cookie是暫時的,也就幾天的有效期,也就是說在這個有效期內,你用你寫的那套代碼可以得到結果,有效期一旦一過就不行了,怎么看cookie有效期,f12調試工具->application->cookies:
如下:
說白了就是,網上那些朋友發的博文到這就結束的,用的代碼都是臨時的,不是永久有效的
分析破解
那么上面的cookie那么多,我們都要一個一個去找它是怎么生成的嗎?經過我的分析發現,其實cookie中只需要帶上一個參數(上面說的無效原因的參數就是這個參數)就行:
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36', 'Cookie': _qddagsx_02095bad0b=ce61f2a659adb14f8a169b6f6e05c81a5ba0b7c10c14dab079ac59c11837474633c1cf8d45a58a941043e96faadd7e87a1ed7dd0a20cbc96ab5c957d44eab96abc9fb0317a0d72926ee0051947182f60999b701f7a8e1e7b41f74d9b54e46a352835f09034c3c7fd72247adcbf81fae7b154b077d24d4d17274167c1291cbe0d }
對,就是 【_qddagsx_02095bad0b】,也就是這里面最長的字段,這個參數就是驗證的核心,根本不是服務端返回的。好,終於到關鍵的地方了
我開始找它這個字段是哪里來的:
用這個字段在網站源碼里查找,很快就找到了
源碼:
function RsaFunc() { setMaxDigits(129); var key = new RSAKeyPair("010001", "", "D718814C9DA3C7F8BB1D414C6B503737886F47FD4BA3E6EF164D9BFA0783AD8255C8401AEE4083794C89D3D4F79E6541DA824E4CC357194C6B02DA19DF84F4FC046137475D089DD07304E86D9508E68633C9454019DDC4B8ED6D24381BEF9071593219067DB4B121FE95471396B07D25850EA7FA4F5E27EB24EE29E158F99831"); var val = "jP5efJMT_jbWimCvZ_hsxW4TdjuV2YWqLPqXcM5gd7c"; var RsaEncrypted = encryptedString(key, val); var isReflash = false; var ck = "_qddagsx_02095bad0b"; if (getCookie(ck) == null) { isReflash = true; } setCookie(ck, RsaEncrypted, 2); if (isReflash) { window.location = window.location; } } RsaFunc();
此時的我突然就來興致了,這里面關鍵的js代碼就是兩個函數:RSAKeyPair和encryptedString
然后我開始找這兩個函數的源碼和用法
RSAKeyPair
經過我的研究發現,其實最關鍵的就是這個函數,其實它並不是函數,而是一個對象,是引入RSA.js暴露出來的對象
好的,這個放一邊
encryptedString
這個函數也是RSA.js里的:
第三方js
再經過我的發現,其實還借用了BigInt.js和Barrettt.js
好的,有了眉目之后,將關鍵的代碼放到本地測試,再經過我的調整,代碼如下:
訪問這個html文件,看控制台的輸出:
發現成了,卧槽,我那個激動啊
然后用這個字段跟之前瀏覽器訪問的對比:
反正長度是一樣了,不知道對不對了,我還發現,每次運行得到的結果都是不一樣的,不管那么多,直接復制新生成的去請求:
header改為如下:
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
'Cookie':_qddagsx_02095bad0b=45e74e67a1622189d14eb9f5441e435e2959cad917cb7bdf369ae8d91529a4ca8fa63f8b4e04a92ea7322e860476874b4e38bc65ffeeec1368c773037a3245f3c5384408dea3ed2c731b7bcfe233465155865be11c3f219902dfc729387b3fffa392b1b633b392da0232d0c6f4ea54f94a62fc6ab99b3b601598dbb739f69e6e }
import requests url = '' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36', 'Cookie':_qddagsx_02095bad0b=45e74e67a1622189d14eb9f5441e435e2959cad917cb7bdf369ae8d91529a4ca8fa63f8b4e04a92ea7322e860476874b4e38bc65ffeeec1368c773037a3245f3c5384408dea3ed2c731b7bcfe233465155865be11c3f219902dfc729387b3fffa392b1b633b392da0232d0c6f4ea54f94a62fc6ab99b3b601598dbb739f69e6e } req = requests.get(url,headers=headers) res = req.content.decode('utf-8')
發現真的可行,返回結果了,可行,縮減調整js:

/* BigInt */
var biRadixBase = 2; var biRadixBits = 16; var bitsPerDigit = biRadixBits; var biRadix = 1 << 16; // = 2^16 = 65536
var biHalfRadix = biRadix >>> 1; var biRadixSquared = biRadix * biRadix; var maxDigitVal = biRadix - 1; var maxInteger = 9999999999999998; var maxDigits; var ZERO_ARRAY; var bigZero, bigOne; function setMaxDigits(value) { maxDigits = value; ZERO_ARRAY = new Array(maxDigits); for (var iza = 0; iza < ZERO_ARRAY.length; iza++) ZERO_ARRAY[iza] = 0; bigZero = new BigInt(); bigOne = new BigInt(); bigOne.digits[0] = 1; } setMaxDigits(20); var dpl10 = 15; var lr10 = biFromNumber(1000000000000000); function BigInt(flag) { if (typeof flag == "boolean" && flag == true) { this.digits = null; } else { this.digits = ZERO_ARRAY.slice(0); } this.isNeg = false; } function biFromDecimal(s) { var isNeg = s.charAt(0) == '-'; var i = isNeg ? 1 : 0; var result; // Skip leading zeros.
while (i < s.length && s.charAt(i) == '0') ++i; if (i == s.length) { result = new BigInt(); } else { var digitCount = s.length - i; var fgl = digitCount % dpl10; if (fgl == 0) fgl = dpl10; result = biFromNumber(Number(s.substr(i, fgl))); i += fgl; while (i < s.length) { result = biAdd(biMultiply(result, lr10), biFromNumber(Number(s.substr(i, dpl10)))); i += dpl10; } result.isNeg = isNeg; } return result; } function biCopy(bi) { var result = new BigInt(true); result.digits = bi.digits.slice(0); result.isNeg = bi.isNeg; return result; } function biFromNumber(i) { var result = new BigInt(); result.isNeg = i < 0; i = Math.abs(i); var j = 0; while (i > 0) { result.digits[j++] = i & maxDigitVal; i = Math.floor(i / biRadix); } return result; } function reverseStr(s) { var result = ""; for (var i = s.length - 1; i > -1; --i) { result += s.charAt(i); } return result; } var hexatrigesimalToChar = new Array( '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' ); function biToString(x, radix) // 2 <= radix <= 36
{ var b = new BigInt(); b.digits[0] = radix; var qr = biDivideModulo(x, b); var result = hexatrigesimalToChar[qr[1].digits[0]]; while (biCompare(qr[0], bigZero) == 1) { qr = biDivideModulo(qr[0], b); digit = qr[1].digits[0]; result += hexatrigesimalToChar[qr[1].digits[0]]; } return (x.isNeg ? "-" : "") + reverseStr(result); } function biToDecimal(x) { var b = new BigInt(); b.digits[0] = 10; var qr = biDivideModulo(x, b); var result = String(qr[1].digits[0]); while (biCompare(qr[0], bigZero) == 1) { qr = biDivideModulo(qr[0], b); result += String(qr[1].digits[0]); } return (x.isNeg ? "-" : "") + reverseStr(result); } var hexToChar = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'); function digitToHex(n) { var mask = 0xf; var result = ""; for (i = 0; i < 4; ++i) { result += hexToChar[n & mask]; n >>>= 4; } return reverseStr(result); } function biToHex(x) { var result = ""; var n = biHighIndex(x); for (var i = biHighIndex(x); i > -1; --i) { result += digitToHex(x.digits[i]); } return result; } function charToHex(c) { var ZERO = 48; var NINE = ZERO + 9; var littleA = 97; var littleZ = littleA + 25; var bigA = 65; var bigZ = 65 + 25; var result; if (c >= ZERO && c <= NINE) { result = c - ZERO; } else if (c >= bigA && c <= bigZ) { result = 10 + c - bigA; } else if (c >= littleA && c <= littleZ) { result = 10 + c - littleA; } else { result = 0; } return result; } function hexToDigit(s) { var result = 0; var sl = Math.min(s.length, 4); for (var i = 0; i < sl; ++i) { result <<= 4; result |= charToHex(s.charCodeAt(i)) } return result; } function biFromHex(s) { var result = new BigInt(); var sl = s.length; for (var i = sl, j = 0; i > 0; i -= 4, ++j) { result.digits[j] = hexToDigit(s.substr(Math.max(i - 4, 0), Math.min(i, 4))); } return result; } function biFromString(s, radix) { var isNeg = s.charAt(0) == '-'; var istop = isNeg ? 1 : 0; var result = new BigInt(); var place = new BigInt(); place.digits[0] = 1; // radix^0
for (var i = s.length - 1; i >= istop; i--) { var c = s.charCodeAt(i); var digit = charToHex(c); var biDigit = biMultiplyDigit(place, digit); result = biAdd(result, biDigit); place = biMultiplyDigit(place, radix); } result.isNeg = isNeg; return result; } function biDump(b) { return (b.isNeg ? "-" : "") + b.digits.join(" "); } function biAdd(x, y) { var result; if (x.isNeg != y.isNeg) { y.isNeg = !y.isNeg; result = biSubtract(x, y); y.isNeg = !y.isNeg; } else { result = new BigInt(); var c = 0; var n; for (var i = 0; i < x.digits.length; ++i) { n = x.digits[i] + y.digits[i] + c; result.digits[i] = n % biRadix; c = Number(n >= biRadix); } result.isNeg = x.isNeg; } return result; } function biSubtract(x, y) { var result; if (x.isNeg != y.isNeg) { y.isNeg = !y.isNeg; result = biAdd(x, y); y.isNeg = !y.isNeg; } else { result = new BigInt(); var n, c; c = 0; for (var i = 0; i < x.digits.length; ++i) { n = x.digits[i] - y.digits[i] + c; result.digits[i] = n % biRadix; // Stupid non-conforming modulus operation.
if (result.digits[i] < 0) result.digits[i] += biRadix; c = 0 - Number(n < 0); } // Fix up the negative sign, if any.
if (c == -1) { c = 0; for (var i = 0; i < x.digits.length; ++i) { n = 0 - result.digits[i] + c; result.digits[i] = n % biRadix; // Stupid non-conforming modulus operation.
if (result.digits[i] < 0) result.digits[i] += biRadix; c = 0 - Number(n < 0); } // Result is opposite sign of arguments.
result.isNeg = !x.isNeg; } else { // Result is same sign.
result.isNeg = x.isNeg; } } return result; } function biHighIndex(x) { var result = x.digits.length - 1; while (result > 0 && x.digits[result] == 0) --result; return result; } function biNumBits(x) { var n = biHighIndex(x); var d = x.digits[n]; var m = (n + 1) * bitsPerDigit; var result; for (result = m; result > m - bitsPerDigit; --result) { if ((d & 0x8000) != 0) break; d <<= 1; } return result; } function biMultiply(x, y) { var result = new BigInt(); var c; var n = biHighIndex(x); var t = biHighIndex(y); var u, uv, k; for (var i = 0; i <= t; ++i) { c = 0; k = i; for (j = 0; j <= n; ++j, ++k) { uv = result.digits[k] + x.digits[j] * y.digits[i] + c; result.digits[k] = uv & maxDigitVal; c = uv >>> biRadixBits; //c = Math.floor(uv / biRadix);
} result.digits[i + n + 1] = c; } // Someone give me a logical xor, please.
result.isNeg = x.isNeg != y.isNeg; return result; } function biMultiplyDigit(x, y) { var n, c, uv; result = new BigInt(); n = biHighIndex(x); c = 0; for (var j = 0; j <= n; ++j) { uv = result.digits[j] + x.digits[j] * y + c; result.digits[j] = uv & maxDigitVal; c = uv >>> biRadixBits; //c = Math.floor(uv / biRadix);
} result.digits[1 + n] = c; return result; } function arrayCopy(src, srcStart, dest, destStart, n) { var m = Math.min(srcStart + n, src.length); for (var i = srcStart, j = destStart; i < m; ++i, ++j) { dest[j] = src[i]; } } var highBitMasks = new Array(0x0000, 0x8000, 0xC000, 0xE000, 0xF000, 0xF800, 0xFC00, 0xFE00, 0xFF00, 0xFF80, 0xFFC0, 0xFFE0, 0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0xFFFF); function biShiftLeft(x, n) { var digitCount = Math.floor(n / bitsPerDigit); var result = new BigInt(); arrayCopy(x.digits, 0, result.digits, digitCount, result.digits.length - digitCount); var bits = n % bitsPerDigit; var rightBits = bitsPerDigit - bits; for (var i = result.digits.length - 1, i1 = i - 1; i > 0; --i, --i1) { result.digits[i] = ((result.digits[i] << bits) & maxDigitVal) | ((result.digits[i1] & highBitMasks[bits]) >>> (rightBits)); } result.digits[0] = ((result.digits[i] << bits) & maxDigitVal); result.isNeg = x.isNeg; return result; } var lowBitMasks = new Array(0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF); function biShiftRight(x, n) { var digitCount = Math.floor(n / bitsPerDigit); var result = new BigInt(); arrayCopy(x.digits, digitCount, result.digits, 0, x.digits.length - digitCount); var bits = n % bitsPerDigit; var leftBits = bitsPerDigit - bits; for (var i = 0, i1 = i + 1; i < result.digits.length - 1; ++i, ++i1) { result.digits[i] = (result.digits[i] >>> bits) | ((result.digits[i1] & lowBitMasks[bits]) << leftBits); } result.digits[result.digits.length - 1] >>>= bits; result.isNeg = x.isNeg; return result; } function biMultiplyByRadixPower(x, n) { var result = new BigInt(); arrayCopy(x.digits, 0, result.digits, n, result.digits.length - n); return result; } function biDivideByRadixPower(x, n) { var result = new BigInt(); arrayCopy(x.digits, n, result.digits, 0, result.digits.length - n); return result; } function biModuloByRadixPower(x, n) { var result = new BigInt(); arrayCopy(x.digits, 0, result.digits, 0, n); return result; } function biCompare(x, y) { if (x.isNeg != y.isNeg) { return 1 - 2 * Number(x.isNeg); } for (var i = x.digits.length - 1; i >= 0; --i) { if (x.digits[i] != y.digits[i]) { if (x.isNeg) { return 1 - 2 * Number(x.digits[i] > y.digits[i]); } else { return 1 - 2 * Number(x.digits[i] < y.digits[i]); } } } return 0; } function biDivideModulo(x, y) { var nb = biNumBits(x); var tb = biNumBits(y); var origYIsNeg = y.isNeg; var q, r; if (nb < tb) { // |x| < |y|
if (x.isNeg) { q = biCopy(bigOne); q.isNeg = !y.isNeg; x.isNeg = false; y.isNeg = false; r = biSubtract(y, x); // Restore signs, 'cause they're references.
x.isNeg = true; y.isNeg = origYIsNeg; } else { q = new BigInt(); r = biCopy(x); } return new Array(q, r); } q = new BigInt(); r = x; // Normalize Y.
var t = Math.ceil(tb / bitsPerDigit) - 1; var lambda = 0; while (y.digits[t] < biHalfRadix) { y = biShiftLeft(y, 1); ++lambda; ++tb; t = Math.ceil(tb / bitsPerDigit) - 1; } r = biShiftLeft(r, lambda); nb += lambda; // Update the bit count for x.
var n = Math.ceil(nb / bitsPerDigit) - 1; var b = biMultiplyByRadixPower(y, n - t); while (biCompare(r, b) != -1) { ++q.digits[n - t]; r = biSubtract(r, b); } for (var i = n; i > t; --i) { var ri = (i >= r.digits.length) ? 0 : r.digits[i]; var ri1 = (i - 1 >= r.digits.length) ? 0 : r.digits[i - 1]; var ri2 = (i - 2 >= r.digits.length) ? 0 : r.digits[i - 2]; var yt = (t >= y.digits.length) ? 0 : y.digits[t]; var yt1 = (t - 1 >= y.digits.length) ? 0 : y.digits[t - 1]; if (ri == yt) { q.digits[i - t - 1] = maxDigitVal; } else { q.digits[i - t - 1] = Math.floor((ri * biRadix + ri1) / yt); } var c1 = q.digits[i - t - 1] * ((yt * biRadix) + yt1); var c2 = (ri * biRadixSquared) + ((ri1 * biRadix) + ri2); while (c1 > c2) { --q.digits[i - t - 1]; c1 = q.digits[i - t - 1] * ((yt * biRadix) | yt1); c2 = (ri * biRadix * biRadix) + ((ri1 * biRadix) + ri2); } b = biMultiplyByRadixPower(y, i - t - 1); r = biSubtract(r, biMultiplyDigit(b, q.digits[i - t - 1])); if (r.isNeg) { r = biAdd(r, b); --q.digits[i - t - 1]; } } r = biShiftRight(r, lambda); // Fiddle with the signs and stuff to make sure that 0 <= r < y.
q.isNeg = x.isNeg != origYIsNeg; if (x.isNeg) { if (origYIsNeg) { q = biAdd(q, bigOne); } else { q = biSubtract(q, bigOne); } y = biShiftRight(y, lambda); r = biSubtract(y, r); } // Check for the unbelievably stupid degenerate case of r == -0.
if (r.digits[0] == 0 && biHighIndex(r) == 0) r.isNeg = false; return new Array(q, r); } function biDivide(x, y) { return biDivideModulo(x, y)[0]; } function biModulo(x, y) { return biDivideModulo(x, y)[1]; } function biMultiplyMod(x, y, m) { return biModulo(biMultiply(x, y), m); } function biPow(x, y) { var result = bigOne; var a = x; while (true) { if ((y & 1) != 0) result = biMultiply(result, a); y >>= 1; if (y == 0) break; a = biMultiply(a, a); } return result; } function biPowMod(x, y, m) { var result = bigOne; var a = x; var k = y; while (true) { if ((k.digits[0] & 1) != 0) result = biMultiplyMod(result, a, m); k = biShiftRight(k, 1); if (k.digits[0] == 0 && biHighIndex(k) == 0) break; a = biMultiplyMod(a, a, m); } return result; } // -----------------------------
/* RSA */
function RSAKeyPair(encryptionExponent, decryptionExponent, modulus) { this.e = biFromHex(encryptionExponent); this.d = biFromHex(decryptionExponent); this.m = biFromHex(modulus); this.digitSize = 2 * biHighIndex(this.m) + 2; this.chunkSize = this.digitSize - 11; this.radix = 16; this.barrett = new BarrettMu(this.m); } function twoDigit(n) { return (n < 10 ? "0" : "") + String(n); } function encryptedString(key, s) { if (key.chunkSize > key.digitSize - 11) { return "Error"; } var a = new Array(); var sl = s.length; var i = 0; while (i < sl) { a[i] = s.charCodeAt(i); i++; } var al = a.length; var result = ""; var j, k, block; for (i = 0; i < al; i += key.chunkSize) { block = new BigInt(); j = 0; var x; var msgLength = (i+key.chunkSize)>al ? al%key.chunkSize : key.chunkSize; var b = new Array(); for (x=0; x<msgLength; x++) { b[x] = a[i+msgLength-1-x]; } b[msgLength] = 0; // marker
var paddedSize = Math.max(8, key.digitSize - 3 - msgLength); for (x=0; x<paddedSize; x++) { b[msgLength+1+x] = Math.floor(Math.random()*254) + 1; // [1,255]
} // It can be asserted that msgLength+paddedSize == key.digitSize-3
b[key.digitSize-2] = 2; // marker
b[key.digitSize-1] = 0; // marker
for (k = 0; k < key.digitSize; ++j) { block.digits[j] = b[k++]; block.digits[j] += b[k++] << 8; } var crypt = key.barrett.powMod(block, key.e); var text = key.radix == 16 ? biToHex(crypt) : biToString(crypt, key.radix); result += text + " "; } return result.substring(0, result.length - 1); // Remove last space.
} function decryptedString(key, s) { var blocks = s.split(" "); var result = ""; var i, j, block; for (i = 0; i < blocks.length; ++i) { var bi; if (key.radix == 16) { bi = biFromHex(blocks[i]); } else { bi = biFromString(blocks[i], key.radix); } block = key.barrett.powMod(bi, key.d); for (j = 0; j <= biHighIndex(block); ++j) { result += String.fromCharCode(block.digits[j] & 255, block.digits[j] >> 8); } } // Remove trailing null, if any.
if (result.charCodeAt(result.length - 1) == 0) { result = result.substring(0, result.length - 1); } return result; } // -----------------------------
/* Barrett */
function BarrettMu(m) { this.modulus = biCopy(m); this.k = biHighIndex(this.modulus) + 1; var b2k = new BigInt(); b2k.digits[2 * this.k] = 1; // b2k = b^(2k)
this.mu = biDivide(b2k, this.modulus); this.bkplus1 = new BigInt(); this.bkplus1.digits[this.k + 1] = 1; // bkplus1 = b^(k+1)
this.modulo = BarrettMu_modulo; this.multiplyMod = BarrettMu_multiplyMod; this.powMod = BarrettMu_powMod; } function BarrettMu_modulo(x) { var q1 = biDivideByRadixPower(x, this.k - 1); var q2 = biMultiply(q1, this.mu); var q3 = biDivideByRadixPower(q2, this.k + 1); var r1 = biModuloByRadixPower(x, this.k + 1); var r2term = biMultiply(q3, this.modulus); var r2 = biModuloByRadixPower(r2term, this.k + 1); var r = biSubtract(r1, r2); if (r.isNeg) { r = biAdd(r, this.bkplus1); } var rgtem = biCompare(r, this.modulus) >= 0; while (rgtem) { r = biSubtract(r, this.modulus); rgtem = biCompare(r, this.modulus) >= 0; } return r; } function BarrettMu_multiplyMod(x, y) { var xy = biMultiply(x, y); return this.modulo(xy); } function BarrettMu_powMod(x, y) { var result = new BigInt(); result.digits[0] = 1; var a = x; var k = y; while (true) { if ((k.digits[0] & 1) != 0) result = this.multiplyMod(result, a); k = biShiftRight(k, 1); if (k.digits[0] == 0 && biHighIndex(k) == 0) break; a = this.multiplyMod(a, a); } return result; } // -----------------------------
function RsaFunc() { setMaxDigits(129); var key = new RSAKeyPair("010001", "", "D718814C9DA3C7F8BB1D414C6B503737886F47FD4BA3E6EF164D9BFA0783AD8255C8401AEE4083794C89D3D4F79E6541DA824E4CC357194C6B02DA19DF84F4FC046137475D089DD07304E86D9508E68633C9454019DDC4B8ED6D24381BEF9071593219067DB4B121FE95471396B07D25850EA7FA4F5E27EB24EE29E158F99831"); var val = "jP5efJMT_jb-ACPiy4oTRhq01UbQ3LOZfm3Y9ptBN4Y"; var RsaEncrypted = encryptedString(key, val); return RsaEncrypted; }
好的,把那段js換成本地的,然后execjs執行js,然后得到封裝到headers里就行了:
順便再說一句,這里用js2py行不通,用execjs可行,我也不知道為啥,用js2py會直接在運行那段js代碼的時候卡住,用execjs在幾秒內就可以生成那段rsa_key

#!/usr/bin/env python # -*- coding:utf-8 -*- # @Author : Eeyhan # @File : test3.py
import requests import execjs requests.packages.urllib3.disable_warnings() requests.adapters.DEFAULT_RETRIES = 5 js = ''' /* BigInt */ var biRadixBase = 2; var biRadixBits = 16; var bitsPerDigit = biRadixBits; var biRadix = 1 << 16; // = 2^16 = 65536 var biHalfRadix = biRadix >>> 1; var biRadixSquared = biRadix * biRadix; var maxDigitVal = biRadix - 1; var maxInteger = 9999999999999998; var maxDigits; var ZERO_ARRAY; var bigZero, bigOne; function setMaxDigits(value) { maxDigits = value; ZERO_ARRAY = new Array(maxDigits); for (var iza = 0; iza < ZERO_ARRAY.length; iza++) ZERO_ARRAY[iza] = 0; bigZero = new BigInt(); bigOne = new BigInt(); bigOne.digits[0] = 1; } setMaxDigits(20); var dpl10 = 15; var lr10 = biFromNumber(1000000000000000); function BigInt(flag) { if (typeof flag == "boolean" && flag == true) { this.digits = null; } else { this.digits = ZERO_ARRAY.slice(0); } this.isNeg = false; } function biFromDecimal(s) { var isNeg = s.charAt(0) == '-'; var i = isNeg ? 1 : 0; var result; // Skip leading zeros. while (i < s.length && s.charAt(i) == '0') ++i; if (i == s.length) { result = new BigInt(); } else { var digitCount = s.length - i; var fgl = digitCount % dpl10; if (fgl == 0) fgl = dpl10; result = biFromNumber(Number(s.substr(i, fgl))); i += fgl; while (i < s.length) { result = biAdd(biMultiply(result, lr10), biFromNumber(Number(s.substr(i, dpl10)))); i += dpl10; } result.isNeg = isNeg; } return result; } function biCopy(bi) { var result = new BigInt(true); result.digits = bi.digits.slice(0); result.isNeg = bi.isNeg; return result; } function biFromNumber(i) { var result = new BigInt(); result.isNeg = i < 0; i = Math.abs(i); var j = 0; while (i > 0) { result.digits[j++] = i & maxDigitVal; i = Math.floor(i / biRadix); } return result; } function reverseStr(s) { var result = ""; for (var i = s.length - 1; i > -1; --i) { result += s.charAt(i); } return result; } var hexatrigesimalToChar = new Array( '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' ); function biToString(x, radix) // 2 <= radix <= 36 { var b = new BigInt(); b.digits[0] = radix; var qr = biDivideModulo(x, b); var result = hexatrigesimalToChar[qr[1].digits[0]]; while (biCompare(qr[0], bigZero) == 1) { qr = biDivideModulo(qr[0], b); digit = qr[1].digits[0]; result += hexatrigesimalToChar[qr[1].digits[0]]; } return (x.isNeg ? "-" : "") + reverseStr(result); } function biToDecimal(x) { var b = new BigInt(); b.digits[0] = 10; var qr = biDivideModulo(x, b); var result = String(qr[1].digits[0]); while (biCompare(qr[0], bigZero) == 1) { qr = biDivideModulo(qr[0], b); result += String(qr[1].digits[0]); } return (x.isNeg ? "-" : "") + reverseStr(result); } var hexToChar = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'); function digitToHex(n) { var mask = 0xf; var result = ""; for (i = 0; i < 4; ++i) { result += hexToChar[n & mask]; n >>>= 4; } return reverseStr(result); } function biToHex(x) { var result = ""; var n = biHighIndex(x); for (var i = biHighIndex(x); i > -1; --i) { result += digitToHex(x.digits[i]); } return result; } function charToHex(c) { var ZERO = 48; var NINE = ZERO + 9; var littleA = 97; var littleZ = littleA + 25; var bigA = 65; var bigZ = 65 + 25; var result; if (c >= ZERO && c <= NINE) { result = c - ZERO; } else if (c >= bigA && c <= bigZ) { result = 10 + c - bigA; } else if (c >= littleA && c <= littleZ) { result = 10 + c - littleA; } else { result = 0; } return result; } function hexToDigit(s) { var result = 0; var sl = Math.min(s.length, 4); for (var i = 0; i < sl; ++i) { result <<= 4; result |= charToHex(s.charCodeAt(i)) } return result; } function biFromHex(s) { var result = new BigInt(); var sl = s.length; for (var i = sl, j = 0; i > 0; i -= 4, ++j) { result.digits[j] = hexToDigit(s.substr(Math.max(i - 4, 0), Math.min(i, 4))); } return result; } function biFromString(s, radix) { var isNeg = s.charAt(0) == '-'; var istop = isNeg ? 1 : 0; var result = new BigInt(); var place = new BigInt(); place.digits[0] = 1; // radix^0 for (var i = s.length - 1; i >= istop; i--) { var c = s.charCodeAt(i); var digit = charToHex(c); var biDigit = biMultiplyDigit(place, digit); result = biAdd(result, biDigit); place = biMultiplyDigit(place, radix); } result.isNeg = isNeg; return result; } function biDump(b) { return (b.isNeg ? "-" : "") + b.digits.join(" "); } function biAdd(x, y) { var result; if (x.isNeg != y.isNeg) { y.isNeg = !y.isNeg; result = biSubtract(x, y); y.isNeg = !y.isNeg; } else { result = new BigInt(); var c = 0; var n; for (var i = 0; i < x.digits.length; ++i) { n = x.digits[i] + y.digits[i] + c; result.digits[i] = n % biRadix; c = Number(n >= biRadix); } result.isNeg = x.isNeg; } return result; } function biSubtract(x, y) { var result; if (x.isNeg != y.isNeg) { y.isNeg = !y.isNeg; result = biAdd(x, y); y.isNeg = !y.isNeg; } else { result = new BigInt(); var n, c; c = 0; for (var i = 0; i < x.digits.length; ++i) { n = x.digits[i] - y.digits[i] + c; result.digits[i] = n % biRadix; // Stupid non-conforming modulus operation. if (result.digits[i] < 0) result.digits[i] += biRadix; c = 0 - Number(n < 0); } // Fix up the negative sign, if any. if (c == -1) { c = 0; for (var i = 0; i < x.digits.length; ++i) { n = 0 - result.digits[i] + c; result.digits[i] = n % biRadix; // Stupid non-conforming modulus operation. if (result.digits[i] < 0) result.digits[i] += biRadix; c = 0 - Number(n < 0); } // Result is opposite sign of arguments. result.isNeg = !x.isNeg; } else { // Result is same sign. result.isNeg = x.isNeg; } } return result; } function biHighIndex(x) { var result = x.digits.length - 1; while (result > 0 && x.digits[result] == 0) --result; return result; } function biNumBits(x) { var n = biHighIndex(x); var d = x.digits[n]; var m = (n + 1) * bitsPerDigit; var result; for (result = m; result > m - bitsPerDigit; --result) { if ((d & 0x8000) != 0) break; d <<= 1; } return result; } function biMultiply(x, y) { var result = new BigInt(); var c; var n = biHighIndex(x); var t = biHighIndex(y); var u, uv, k; for (var i = 0; i <= t; ++i) { c = 0; k = i; for (j = 0; j <= n; ++j, ++k) { uv = result.digits[k] + x.digits[j] * y.digits[i] + c; result.digits[k] = uv & maxDigitVal; c = uv >>> biRadixBits; //c = Math.floor(uv / biRadix); } result.digits[i + n + 1] = c; } // Someone give me a logical xor, please. result.isNeg = x.isNeg != y.isNeg; return result; } function biMultiplyDigit(x, y) { var n, c, uv; result = new BigInt(); n = biHighIndex(x); c = 0; for (var j = 0; j <= n; ++j) { uv = result.digits[j] + x.digits[j] * y + c; result.digits[j] = uv & maxDigitVal; c = uv >>> biRadixBits; //c = Math.floor(uv / biRadix); } result.digits[1 + n] = c; return result; } function arrayCopy(src, srcStart, dest, destStart, n) { var m = Math.min(srcStart + n, src.length); for (var i = srcStart, j = destStart; i < m; ++i, ++j) { dest[j] = src[i]; } } var highBitMasks = new Array(0x0000, 0x8000, 0xC000, 0xE000, 0xF000, 0xF800, 0xFC00, 0xFE00, 0xFF00, 0xFF80, 0xFFC0, 0xFFE0, 0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0xFFFF); function biShiftLeft(x, n) { var digitCount = Math.floor(n / bitsPerDigit); var result = new BigInt(); arrayCopy(x.digits, 0, result.digits, digitCount, result.digits.length - digitCount); var bits = n % bitsPerDigit; var rightBits = bitsPerDigit - bits; for (var i = result.digits.length - 1, i1 = i - 1; i > 0; --i, --i1) { result.digits[i] = ((result.digits[i] << bits) & maxDigitVal) | ((result.digits[i1] & highBitMasks[bits]) >>> (rightBits)); } result.digits[0] = ((result.digits[i] << bits) & maxDigitVal); result.isNeg = x.isNeg; return result; } var lowBitMasks = new Array(0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF); function biShiftRight(x, n) { var digitCount = Math.floor(n / bitsPerDigit); var result = new BigInt(); arrayCopy(x.digits, digitCount, result.digits, 0, x.digits.length - digitCount); var bits = n % bitsPerDigit; var leftBits = bitsPerDigit - bits; for (var i = 0, i1 = i + 1; i < result.digits.length - 1; ++i, ++i1) { result.digits[i] = (result.digits[i] >>> bits) | ((result.digits[i1] & lowBitMasks[bits]) << leftBits); } result.digits[result.digits.length - 1] >>>= bits; result.isNeg = x.isNeg; return result; } function biMultiplyByRadixPower(x, n) { var result = new BigInt(); arrayCopy(x.digits, 0, result.digits, n, result.digits.length - n); return result; } function biDivideByRadixPower(x, n) { var result = new BigInt(); arrayCopy(x.digits, n, result.digits, 0, result.digits.length - n); return result; } function biModuloByRadixPower(x, n) { var result = new BigInt(); arrayCopy(x.digits, 0, result.digits, 0, n); return result; } function biCompare(x, y) { if (x.isNeg != y.isNeg) { return 1 - 2 * Number(x.isNeg); } for (var i = x.digits.length - 1; i >= 0; --i) { if (x.digits[i] != y.digits[i]) { if (x.isNeg) { return 1 - 2 * Number(x.digits[i] > y.digits[i]); } else { return 1 - 2 * Number(x.digits[i] < y.digits[i]); } } } return 0; } function biDivideModulo(x, y) { var nb = biNumBits(x); var tb = biNumBits(y); var origYIsNeg = y.isNeg; var q, r; if (nb < tb) { // |x| < |y| if (x.isNeg) { q = biCopy(bigOne); q.isNeg = !y.isNeg; x.isNeg = false; y.isNeg = false; r = biSubtract(y, x); // Restore signs, 'cause they're references. x.isNeg = true; y.isNeg = origYIsNeg; } else { q = new BigInt(); r = biCopy(x); } return new Array(q, r); } q = new BigInt(); r = x; // Normalize Y. var t = Math.ceil(tb / bitsPerDigit) - 1; var lambda = 0; while (y.digits[t] < biHalfRadix) { y = biShiftLeft(y, 1); ++lambda; ++tb; t = Math.ceil(tb / bitsPerDigit) - 1; } r = biShiftLeft(r, lambda); nb += lambda; // Update the bit count for x. var n = Math.ceil(nb / bitsPerDigit) - 1; var b = biMultiplyByRadixPower(y, n - t); while (biCompare(r, b) != -1) { ++q.digits[n - t]; r = biSubtract(r, b); } for (var i = n; i > t; --i) { var ri = (i >= r.digits.length) ? 0 : r.digits[i]; var ri1 = (i - 1 >= r.digits.length) ? 0 : r.digits[i - 1]; var ri2 = (i - 2 >= r.digits.length) ? 0 : r.digits[i - 2]; var yt = (t >= y.digits.length) ? 0 : y.digits[t]; var yt1 = (t - 1 >= y.digits.length) ? 0 : y.digits[t - 1]; if (ri == yt) { q.digits[i - t - 1] = maxDigitVal; } else { q.digits[i - t - 1] = Math.floor((ri * biRadix + ri1) / yt); } var c1 = q.digits[i - t - 1] * ((yt * biRadix) + yt1); var c2 = (ri * biRadixSquared) + ((ri1 * biRadix) + ri2); while (c1 > c2) { --q.digits[i - t - 1]; c1 = q.digits[i - t - 1] * ((yt * biRadix) | yt1); c2 = (ri * biRadix * biRadix) + ((ri1 * biRadix) + ri2); } b = biMultiplyByRadixPower(y, i - t - 1); r = biSubtract(r, biMultiplyDigit(b, q.digits[i - t - 1])); if (r.isNeg) { r = biAdd(r, b); --q.digits[i - t - 1]; } } r = biShiftRight(r, lambda); // Fiddle with the signs and stuff to make sure that 0 <= r < y. q.isNeg = x.isNeg != origYIsNeg; if (x.isNeg) { if (origYIsNeg) { q = biAdd(q, bigOne); } else { q = biSubtract(q, bigOne); } y = biShiftRight(y, lambda); r = biSubtract(y, r); } // Check for the unbelievably stupid degenerate case of r == -0. if (r.digits[0] == 0 && biHighIndex(r) == 0) r.isNeg = false; return new Array(q, r); } function biDivide(x, y) { return biDivideModulo(x, y)[0]; } function biModulo(x, y) { return biDivideModulo(x, y)[1]; } function biMultiplyMod(x, y, m) { return biModulo(biMultiply(x, y), m); } function biPow(x, y) { var result = bigOne; var a = x; while (true) { if ((y & 1) != 0) result = biMultiply(result, a); y >>= 1; if (y == 0) break; a = biMultiply(a, a); } return result; } function biPowMod(x, y, m) { var result = bigOne; var a = x; var k = y; while (true) { if ((k.digits[0] & 1) != 0) result = biMultiplyMod(result, a, m); k = biShiftRight(k, 1); if (k.digits[0] == 0 && biHighIndex(k) == 0) break; a = biMultiplyMod(a, a, m); } return result; } // ----------------------------- /* RSA */ function RSAKeyPair(encryptionExponent, decryptionExponent, modulus) { this.e = biFromHex(encryptionExponent); this.d = biFromHex(decryptionExponent); this.m = biFromHex(modulus); this.digitSize = 2 * biHighIndex(this.m) + 2; this.chunkSize = this.digitSize - 11; this.radix = 16; this.barrett = new BarrettMu(this.m); } function twoDigit(n) { return (n < 10 ? "0" : "") + String(n); } function encryptedString(key, s) { if (key.chunkSize > key.digitSize - 11) { return "Error"; } var a = new Array(); var sl = s.length; var i = 0; while (i < sl) { a[i] = s.charCodeAt(i); i++; } var al = a.length; var result = ""; var j, k, block; for (i = 0; i < al; i += key.chunkSize) { block = new BigInt(); j = 0; var x; var msgLength = (i+key.chunkSize)>al ? al%key.chunkSize : key.chunkSize; var b = new Array(); for (x=0; x<msgLength; x++) { b[x] = a[i+msgLength-1-x]; } b[msgLength] = 0; // marker var paddedSize = Math.max(8, key.digitSize - 3 - msgLength); for (x=0; x<paddedSize; x++) { b[msgLength+1+x] = Math.floor(Math.random()*254) + 1; // [1,255] } // It can be asserted that msgLength+paddedSize == key.digitSize-3 b[key.digitSize-2] = 2; // marker b[key.digitSize-1] = 0; // marker for (k = 0; k < key.digitSize; ++j) { block.digits[j] = b[k++]; block.digits[j] += b[k++] << 8; } var crypt = key.barrett.powMod(block, key.e); var text = key.radix == 16 ? biToHex(crypt) : biToString(crypt, key.radix); result += text + " "; } return result.substring(0, result.length - 1); // Remove last space. } function decryptedString(key, s) { var blocks = s.split(" "); var result = ""; var i, j, block; for (i = 0; i < blocks.length; ++i) { var bi; if (key.radix == 16) { bi = biFromHex(blocks[i]); } else { bi = biFromString(blocks[i], key.radix); } block = key.barrett.powMod(bi, key.d); for (j = 0; j <= biHighIndex(block); ++j) { result += String.fromCharCode(block.digits[j] & 255, block.digits[j] >> 8); } } // Remove trailing null, if any. if (result.charCodeAt(result.length - 1) == 0) { result = result.substring(0, result.length - 1); } return result; } // ----------------------------- /* Barrett */ function BarrettMu(m) { this.modulus = biCopy(m); this.k = biHighIndex(this.modulus) + 1; var b2k = new BigInt(); b2k.digits[2 * this.k] = 1; // b2k = b^(2k) this.mu = biDivide(b2k, this.modulus); this.bkplus1 = new BigInt(); this.bkplus1.digits[this.k + 1] = 1; // bkplus1 = b^(k+1) this.modulo = BarrettMu_modulo; this.multiplyMod = BarrettMu_multiplyMod; this.powMod = BarrettMu_powMod; } function BarrettMu_modulo(x) { var q1 = biDivideByRadixPower(x, this.k - 1); var q2 = biMultiply(q1, this.mu); var q3 = biDivideByRadixPower(q2, this.k + 1); var r1 = biModuloByRadixPower(x, this.k + 1); var r2term = biMultiply(q3, this.modulus); var r2 = biModuloByRadixPower(r2term, this.k + 1); var r = biSubtract(r1, r2); if (r.isNeg) { r = biAdd(r, this.bkplus1); } var rgtem = biCompare(r, this.modulus) >= 0; while (rgtem) { r = biSubtract(r, this.modulus); rgtem = biCompare(r, this.modulus) >= 0; } return r; } function BarrettMu_multiplyMod(x, y) { var xy = biMultiply(x, y); return this.modulo(xy); } function BarrettMu_powMod(x, y) { var result = new BigInt(); result.digits[0] = 1; var a = x; var k = y; while (true) { if ((k.digits[0] & 1) != 0) result = this.multiplyMod(result, a); k = biShiftRight(k, 1); if (k.digits[0] == 0 && biHighIndex(k) == 0) break; a = this.multiplyMod(a, a); } return result; } // ----------------------------- function RsaFunc() { setMaxDigits(129); var key = new RSAKeyPair("010001", "", "D718814C9DA3C7F8BB1D414C6B503737886F47FD4BA3E6EF164D9BFA0783AD8255C8401AEE4083794C89D3D4F79E6541DA824E4CC357194C6B02DA19DF84F4FC046137475D089DD07304E86D9508E68633C9454019DDC4B8ED6D24381BEF9071593219067DB4B121FE95471396B07D25850EA7FA4F5E27EB24EE29E158F99831"); var val = "jP5efJMT_jb-ACPiy4oTRhq01UbQ3LOZfm3Y9ptBN4Y"; var RsaEncrypted = encryptedString(key, val); return RsaEncrypted; } ''' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36', } data = {'OPtype': 'GetListNew', 'pageSize': '10', 'proArea': '-1', 'announcementType': '-1', 'ProType': '-1', 'xmlx': '-1', 'projectName': '', 'rrr': '0.38874920439722827', 'TopTime': '2020-01-02 00:00:00', 'EndTime': '2020-02-02 23:59:59', 'pageNo': 3, 'category': 'ZFCG'} cx = execjs.compile(js) cookie = cx.call('RsaFunc') print(cookie) cookie = {'Cookie': '_qddagsx_02095bad0b=%s' % cookie} headers.update(cookie) url = '' # 網址保密,自己去找同rsa加密的網站,方法相同
req = requests.post(url, headers=headers, data=data, verify=False) res = req.content.decode('utf-8') print(res)
理論上本篇文章是完了,其實這里還有一個坑,目前還不行,因為也是我的研究發現的,有朋友要問,為什么還不行,不是已經搞定了嗎?真的還沒有,這里還有一個大坑:
回到剛剛解析的RSA函數那里:
根據我的研究,發現圈出區域的字段是會變的,瑪德,你說這里是不是個大坑?不信?我f5刷新下,再看:
變量val變了,其他還有沒有變目前無法得知,那么就得每次要爬取這個網站之前,先獲取一次這個網站的源碼,將這個RsaFunc重組一下:
完整代碼:

#!/usr/bin/env python # -*- coding:utf-8 -*- # @Author : Eeyhan # @File : test3.py
import time import requests import js2py import execjs start = time.time() js = ''' /* BigInt */ var biRadixBase = 2; var biRadixBits = 16; var bitsPerDigit = biRadixBits; var biRadix = 1 << 16; // = 2^16 = 65536 var biHalfRadix = biRadix >>> 1; var biRadixSquared = biRadix * biRadix; var maxDigitVal = biRadix - 1; var maxInteger = 9999999999999998; var maxDigits; var ZERO_ARRAY; var bigZero, bigOne; function setMaxDigits(value) { maxDigits = value; ZERO_ARRAY = new Array(maxDigits); for (var iza = 0; iza < ZERO_ARRAY.length; iza++) ZERO_ARRAY[iza] = 0; bigZero = new BigInt(); bigOne = new BigInt(); bigOne.digits[0] = 1; } setMaxDigits(20); var dpl10 = 15; var lr10 = biFromNumber(1000000000000000); function BigInt(flag) { if (typeof flag == "boolean" && flag == true) { this.digits = null; } else { this.digits = ZERO_ARRAY.slice(0); } this.isNeg = false; } function biFromDecimal(s) { var isNeg = s.charAt(0) == '-'; var i = isNeg ? 1 : 0; var result; // Skip leading zeros. while (i < s.length && s.charAt(i) == '0') ++i; if (i == s.length) { result = new BigInt(); } else { var digitCount = s.length - i; var fgl = digitCount % dpl10; if (fgl == 0) fgl = dpl10; result = biFromNumber(Number(s.substr(i, fgl))); i += fgl; while (i < s.length) { result = biAdd(biMultiply(result, lr10), biFromNumber(Number(s.substr(i, dpl10)))); i += dpl10; } result.isNeg = isNeg; } return result; } function biCopy(bi) { var result = new BigInt(true); result.digits = bi.digits.slice(0); result.isNeg = bi.isNeg; return result; } function biFromNumber(i) { var result = new BigInt(); result.isNeg = i < 0; i = Math.abs(i); var j = 0; while (i > 0) { result.digits[j++] = i & maxDigitVal; i = Math.floor(i / biRadix); } return result; } function reverseStr(s) { var result = ""; for (var i = s.length - 1; i > -1; --i) { result += s.charAt(i); } return result; } var hexatrigesimalToChar = new Array( '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' ); function biToString(x, radix) // 2 <= radix <= 36 { var b = new BigInt(); b.digits[0] = radix; var qr = biDivideModulo(x, b); var result = hexatrigesimalToChar[qr[1].digits[0]]; while (biCompare(qr[0], bigZero) == 1) { qr = biDivideModulo(qr[0], b); digit = qr[1].digits[0]; result += hexatrigesimalToChar[qr[1].digits[0]]; } return (x.isNeg ? "-" : "") + reverseStr(result); } function biToDecimal(x) { var b = new BigInt(); b.digits[0] = 10; var qr = biDivideModulo(x, b); var result = String(qr[1].digits[0]); while (biCompare(qr[0], bigZero) == 1) { qr = biDivideModulo(qr[0], b); result += String(qr[1].digits[0]); } return (x.isNeg ? "-" : "") + reverseStr(result); } var hexToChar = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'); function digitToHex(n) { var mask = 0xf; var result = ""; for (i = 0; i < 4; ++i) { result += hexToChar[n & mask]; n >>>= 4; } return reverseStr(result); } function biToHex(x) { var result = ""; var n = biHighIndex(x); for (var i = biHighIndex(x); i > -1; --i) { result += digitToHex(x.digits[i]); } return result; } function charToHex(c) { var ZERO = 48; var NINE = ZERO + 9; var littleA = 97; var littleZ = littleA + 25; var bigA = 65; var bigZ = 65 + 25; var result; if (c >= ZERO && c <= NINE) { result = c - ZERO; } else if (c >= bigA && c <= bigZ) { result = 10 + c - bigA; } else if (c >= littleA && c <= littleZ) { result = 10 + c - littleA; } else { result = 0; } return result; } function hexToDigit(s) { var result = 0; var sl = Math.min(s.length, 4); for (var i = 0; i < sl; ++i) { result <<= 4; result |= charToHex(s.charCodeAt(i)) } return result; } function biFromHex(s) { var result = new BigInt(); var sl = s.length; for (var i = sl, j = 0; i > 0; i -= 4, ++j) { result.digits[j] = hexToDigit(s.substr(Math.max(i - 4, 0), Math.min(i, 4))); } return result; } function biFromString(s, radix) { var isNeg = s.charAt(0) == '-'; var istop = isNeg ? 1 : 0; var result = new BigInt(); var place = new BigInt(); place.digits[0] = 1; // radix^0 for (var i = s.length - 1; i >= istop; i--) { var c = s.charCodeAt(i); var digit = charToHex(c); var biDigit = biMultiplyDigit(place, digit); result = biAdd(result, biDigit); place = biMultiplyDigit(place, radix); } result.isNeg = isNeg; return result; } function biDump(b) { return (b.isNeg ? "-" : "") + b.digits.join(" "); } function biAdd(x, y) { var result; if (x.isNeg != y.isNeg) { y.isNeg = !y.isNeg; result = biSubtract(x, y); y.isNeg = !y.isNeg; } else { result = new BigInt(); var c = 0; var n; for (var i = 0; i < x.digits.length; ++i) { n = x.digits[i] + y.digits[i] + c; result.digits[i] = n % biRadix; c = Number(n >= biRadix); } result.isNeg = x.isNeg; } return result; } function biSubtract(x, y) { var result; if (x.isNeg != y.isNeg) { y.isNeg = !y.isNeg; result = biAdd(x, y); y.isNeg = !y.isNeg; } else { result = new BigInt(); var n, c; c = 0; for (var i = 0; i < x.digits.length; ++i) { n = x.digits[i] - y.digits[i] + c; result.digits[i] = n % biRadix; // Stupid non-conforming modulus operation. if (result.digits[i] < 0) result.digits[i] += biRadix; c = 0 - Number(n < 0); } // Fix up the negative sign, if any. if (c == -1) { c = 0; for (var i = 0; i < x.digits.length; ++i) { n = 0 - result.digits[i] + c; result.digits[i] = n % biRadix; // Stupid non-conforming modulus operation. if (result.digits[i] < 0) result.digits[i] += biRadix; c = 0 - Number(n < 0); } // Result is opposite sign of arguments. result.isNeg = !x.isNeg; } else { // Result is same sign. result.isNeg = x.isNeg; } } return result; } function biHighIndex(x) { var result = x.digits.length - 1; while (result > 0 && x.digits[result] == 0) --result; return result; } function biNumBits(x) { var n = biHighIndex(x); var d = x.digits[n]; var m = (n + 1) * bitsPerDigit; var result; for (result = m; result > m - bitsPerDigit; --result) { if ((d & 0x8000) != 0) break; d <<= 1; } return result; } function biMultiply(x, y) { var result = new BigInt(); var c; var n = biHighIndex(x); var t = biHighIndex(y); var u, uv, k; for (var i = 0; i <= t; ++i) { c = 0; k = i; for (j = 0; j <= n; ++j, ++k) { uv = result.digits[k] + x.digits[j] * y.digits[i] + c; result.digits[k] = uv & maxDigitVal; c = uv >>> biRadixBits; //c = Math.floor(uv / biRadix); } result.digits[i + n + 1] = c; } // Someone give me a logical xor, please. result.isNeg = x.isNeg != y.isNeg; return result; } function biMultiplyDigit(x, y) { var n, c, uv; result = new BigInt(); n = biHighIndex(x); c = 0; for (var j = 0; j <= n; ++j) { uv = result.digits[j] + x.digits[j] * y + c; result.digits[j] = uv & maxDigitVal; c = uv >>> biRadixBits; //c = Math.floor(uv / biRadix); } result.digits[1 + n] = c; return result; } function arrayCopy(src, srcStart, dest, destStart, n) { var m = Math.min(srcStart + n, src.length); for (var i = srcStart, j = destStart; i < m; ++i, ++j) { dest[j] = src[i]; } } var highBitMasks = new Array(0x0000, 0x8000, 0xC000, 0xE000, 0xF000, 0xF800, 0xFC00, 0xFE00, 0xFF00, 0xFF80, 0xFFC0, 0xFFE0, 0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0xFFFF); function biShiftLeft(x, n) { var digitCount = Math.floor(n / bitsPerDigit); var result = new BigInt(); arrayCopy(x.digits, 0, result.digits, digitCount, result.digits.length - digitCount); var bits = n % bitsPerDigit; var rightBits = bitsPerDigit - bits; for (var i = result.digits.length - 1, i1 = i - 1; i > 0; --i, --i1) { result.digits[i] = ((result.digits[i] << bits) & maxDigitVal) | ((result.digits[i1] & highBitMasks[bits]) >>> (rightBits)); } result.digits[0] = ((result.digits[i] << bits) & maxDigitVal); result.isNeg = x.isNeg; return result; } var lowBitMasks = new Array(0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF); function biShiftRight(x, n) { var digitCount = Math.floor(n / bitsPerDigit); var result = new BigInt(); arrayCopy(x.digits, digitCount, result.digits, 0, x.digits.length - digitCount); var bits = n % bitsPerDigit; var leftBits = bitsPerDigit - bits; for (var i = 0, i1 = i + 1; i < result.digits.length - 1; ++i, ++i1) { result.digits[i] = (result.digits[i] >>> bits) | ((result.digits[i1] & lowBitMasks[bits]) << leftBits); } result.digits[result.digits.length - 1] >>>= bits; result.isNeg = x.isNeg; return result; } function biMultiplyByRadixPower(x, n) { var result = new BigInt(); arrayCopy(x.digits, 0, result.digits, n, result.digits.length - n); return result; } function biDivideByRadixPower(x, n) { var result = new BigInt(); arrayCopy(x.digits, n, result.digits, 0, result.digits.length - n); return result; } function biModuloByRadixPower(x, n) { var result = new BigInt(); arrayCopy(x.digits, 0, result.digits, 0, n); return result; } function biCompare(x, y) { if (x.isNeg != y.isNeg) { return 1 - 2 * Number(x.isNeg); } for (var i = x.digits.length - 1; i >= 0; --i) { if (x.digits[i] != y.digits[i]) { if (x.isNeg) { return 1 - 2 * Number(x.digits[i] > y.digits[i]); } else { return 1 - 2 * Number(x.digits[i] < y.digits[i]); } } } return 0; } function biDivideModulo(x, y) { var nb = biNumBits(x); var tb = biNumBits(y); var origYIsNeg = y.isNeg; var q, r; if (nb < tb) { // |x| < |y| if (x.isNeg) { q = biCopy(bigOne); q.isNeg = !y.isNeg; x.isNeg = false; y.isNeg = false; r = biSubtract(y, x); // Restore signs, 'cause they're references. x.isNeg = true; y.isNeg = origYIsNeg; } else { q = new BigInt(); r = biCopy(x); } return new Array(q, r); } q = new BigInt(); r = x; // Normalize Y. var t = Math.ceil(tb / bitsPerDigit) - 1; var lambda = 0; while (y.digits[t] < biHalfRadix) { y = biShiftLeft(y, 1); ++lambda; ++tb; t = Math.ceil(tb / bitsPerDigit) - 1; } r = biShiftLeft(r, lambda); nb += lambda; // Update the bit count for x. var n = Math.ceil(nb / bitsPerDigit) - 1; var b = biMultiplyByRadixPower(y, n - t); while (biCompare(r, b) != -1) { ++q.digits[n - t]; r = biSubtract(r, b); } for (var i = n; i > t; --i) { var ri = (i >= r.digits.length) ? 0 : r.digits[i]; var ri1 = (i - 1 >= r.digits.length) ? 0 : r.digits[i - 1]; var ri2 = (i - 2 >= r.digits.length) ? 0 : r.digits[i - 2]; var yt = (t >= y.digits.length) ? 0 : y.digits[t]; var yt1 = (t - 1 >= y.digits.length) ? 0 : y.digits[t - 1]; if (ri == yt) { q.digits[i - t - 1] = maxDigitVal; } else { q.digits[i - t - 1] = Math.floor((ri * biRadix + ri1) / yt); } var c1 = q.digits[i - t - 1] * ((yt * biRadix) + yt1); var c2 = (ri * biRadixSquared) + ((ri1 * biRadix) + ri2); while (c1 > c2) { --q.digits[i - t - 1]; c1 = q.digits[i - t - 1] * ((yt * biRadix) | yt1); c2 = (ri * biRadix * biRadix) + ((ri1 * biRadix) + ri2); } b = biMultiplyByRadixPower(y, i - t - 1); r = biSubtract(r, biMultiplyDigit(b, q.digits[i - t - 1])); if (r.isNeg) { r = biAdd(r, b); --q.digits[i - t - 1]; } } r = biShiftRight(r, lambda); // Fiddle with the signs and stuff to make sure that 0 <= r < y. q.isNeg = x.isNeg != origYIsNeg; if (x.isNeg) { if (origYIsNeg) { q = biAdd(q, bigOne); } else { q = biSubtract(q, bigOne); } y = biShiftRight(y, lambda); r = biSubtract(y, r); } // Check for the unbelievably stupid degenerate case of r == -0. if (r.digits[0] == 0 && biHighIndex(r) == 0) r.isNeg = false; return new Array(q, r); } function biDivide(x, y) { return biDivideModulo(x, y)[0]; } function biModulo(x, y) { return biDivideModulo(x, y)[1]; } function biMultiplyMod(x, y, m) { return biModulo(biMultiply(x, y), m); } function biPow(x, y) { var result = bigOne; var a = x; while (true) { if ((y & 1) != 0) result = biMultiply(result, a); y >>= 1; if (y == 0) break; a = biMultiply(a, a); } return result; } function biPowMod(x, y, m) { var result = bigOne; var a = x; var k = y; while (true) { if ((k.digits[0] & 1) != 0) result = biMultiplyMod(result, a, m); k = biShiftRight(k, 1); if (k.digits[0] == 0 && biHighIndex(k) == 0) break; a = biMultiplyMod(a, a, m); } return result; } // ----------------------------- /* RSA */ function RSAKeyPair(encryptionExponent, decryptionExponent, modulus) { this.e = biFromHex(encryptionExponent); this.d = biFromHex(decryptionExponent); this.m = biFromHex(modulus); this.digitSize = 2 * biHighIndex(this.m) + 2; this.chunkSize = this.digitSize - 11; this.radix = 16; this.barrett = new BarrettMu(this.m); } function twoDigit(n) { return (n < 10 ? "0" : "") + String(n); } function encryptedString(key, s) { if (key.chunkSize > key.digitSize - 11) { return "Error"; } var a = new Array(); var sl = s.length; var i = 0; while (i < sl) { a[i] = s.charCodeAt(i); i++; } var al = a.length; var result = ""; var j, k, block; for (i = 0; i < al; i += key.chunkSize) { block = new BigInt(); j = 0; var x; var msgLength = (i+key.chunkSize)>al ? al%key.chunkSize : key.chunkSize; var b = new Array(); for (x=0; x<msgLength; x++) { b[x] = a[i+msgLength-1-x]; } b[msgLength] = 0; // marker var paddedSize = Math.max(8, key.digitSize - 3 - msgLength); for (x=0; x<paddedSize; x++) { b[msgLength+1+x] = Math.floor(Math.random()*254) + 1; // [1,255] } // It can be asserted that msgLength+paddedSize == key.digitSize-3 b[key.digitSize-2] = 2; // marker b[key.digitSize-1] = 0; // marker for (k = 0; k < key.digitSize; ++j) { block.digits[j] = b[k++]; block.digits[j] += b[k++] << 8; } var crypt = key.barrett.powMod(block, key.e); var text = key.radix == 16 ? biToHex(crypt) : biToString(crypt, key.radix); result += text + " "; } return result.substring(0, result.length - 1); // Remove last space. } function decryptedString(key, s) { var blocks = s.split(" "); var result = ""; var i, j, block; for (i = 0; i < blocks.length; ++i) { var bi; if (key.radix == 16) { bi = biFromHex(blocks[i]); } else { bi = biFromString(blocks[i], key.radix); } block = key.barrett.powMod(bi, key.d); for (j = 0; j <= biHighIndex(block); ++j) { result += String.fromCharCode(block.digits[j] & 255, block.digits[j] >> 8); } } // Remove trailing null, if any. if (result.charCodeAt(result.length - 1) == 0) { result = result.substring(0, result.length - 1); } return result; } // ----------------------------- /* Barrett */ function BarrettMu(m) { this.modulus = biCopy(m); this.k = biHighIndex(this.modulus) + 1; var b2k = new BigInt(); b2k.digits[2 * this.k] = 1; // b2k = b^(2k) this.mu = biDivide(b2k, this.modulus); this.bkplus1 = new BigInt(); this.bkplus1.digits[this.k + 1] = 1; // bkplus1 = b^(k+1) this.modulo = BarrettMu_modulo; this.multiplyMod = BarrettMu_multiplyMod; this.powMod = BarrettMu_powMod; } function BarrettMu_modulo(x) { var q1 = biDivideByRadixPower(x, this.k - 1); var q2 = biMultiply(q1, this.mu); var q3 = biDivideByRadixPower(q2, this.k + 1); var r1 = biModuloByRadixPower(x, this.k + 1); var r2term = biMultiply(q3, this.modulus); var r2 = biModuloByRadixPower(r2term, this.k + 1); var r = biSubtract(r1, r2); if (r.isNeg) { r = biAdd(r, this.bkplus1); } var rgtem = biCompare(r, this.modulus) >= 0; while (rgtem) { r = biSubtract(r, this.modulus); rgtem = biCompare(r, this.modulus) >= 0; } return r; } function BarrettMu_multiplyMod(x, y) { var xy = biMultiply(x, y); return this.modulo(xy); } function BarrettMu_powMod(x, y) { var result = new BigInt(); result.digits[0] = 1; var a = x; var k = y; while (true) { if ((k.digits[0] & 1) != 0) result = this.multiplyMod(result, a); k = biShiftRight(k, 1); if (k.digits[0] == 0 && biHighIndex(k) == 0) break; a = this.multiplyMod(a, a); } return result; } // ----------------------------- ''' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36', # 'Cookie': 'ASP.NET_SessionId=minwuelgy2ounvdyz3iy2por; Hm_lvt_db393520fa240b442a13a6d1c5ae95c1=1580346880; Hm_lvt_9d1de05cc99f08ddb5dc6d5e4d32ad30=1580346880; Hm_lvt_94bfa5b89a33cebfead2f88d38657023=1580346880; __root_domain_v=.fujian.gov.cn; _qddaz=QD.3g0yf8.g6u01n.k601qabh; _qdda=4-1.1o7qs8; _qddab=4-4srcpb.k601qagy; _qddamta_2852155767=4-0; _qddagsx_02095bad0b=ce61f2a659adb14f8a169b6f6e05c81a5ba0b7c10c14dab079ac59c11837474633c1cf8d45a58a941043e96faadd7e87a1ed7dd0a20cbc96ab5c957d44eab96abc9fb0317a0d72926ee0051947182f60999b701f7a8e1e7b41f74d9b54e46a352835f09034c3c7fd72247adcbf81fae7b154b077d24d4d17274167c1291cbe0d; Hm_lpvt_9d1de05cc99f08ddb5dc6d5e4d32ad30=1580346887; Hm_lpvt_94bfa5b89a33cebfead2f88d38657023=1580346887; Hm_lpvt_db393520fa240b442a13a6d1c5ae95c1=1580346887'
# 'Cookie': '_qddagsx_02095bad0b=5c321b3c5c77caa787de3129fdaabb5a46f302aa0a98bb1729beb95f93a7783cc013259f43161694cb6e0e9b40040a8e5926a49e3b1e7d43c043aee70426627852c537f5759699728b0a7675eb72169844ff43b47f70a62ea17a5476c66db2e177f7eca1384f55a665d3d2bec41a7bcb3ff118f8aabc79a5d995f5aabc901a0d'
} url = '' req = requests.get(url, headers=headers, verify=False) res = req.content.decode('utf-8') start_index = res.index('function RsaFunc') end_index = res.index('var isReflash = false;') rsafunc = res[start_index:end_index] rsafunc += 'return RsaEncrypted;\n}' js += rsafunc cx = execjs.compile(js) cookie = cx.call('RsaFunc') cookie = {'Cookie': '_qddagsx_02095bad0b=%s' % rsa_key} headers.update(cookie) url2 = '' req = requests.post(url2, headers=headers, data=data, verify=False) res = req.content.decode('utf-8')
這樣才算是好了,這才是真的破解了這個網站的反爬機制
對了,本篇文章不是破解RSA的加密,而是破解的帶有這種方式的反爬機制
ok,完畢!!