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

前言

 

同上一篇的aes加密一样,也是偶然发现这个rsa加密的,目标网站我就不说了,保密。

 

当我发现这个网站是ajax加载时:

python爬虫破解带有RSA.js的RSA加密数据的反爬机制 Python 第1张

 

 

 

我已经习以为常,正在进行爬取时,发现返回为空,我开始用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复制出来吗?想想这样繁琐不?

 

因为都知道,cookie是暂时的,也就几天的有效期,也就是是在这个有效期内,你用你写的那套代码可以得到结果,有效期一过就不行了,怎么看cookie有效期,f12调试工具->application->cookies:

 

如下:

 

python爬虫破解带有RSA.js的RSA加密数据的反爬机制 Python 第2张

 

分析破解

 

那么上面的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】,也就是这里面最长的字段,好,终于到关键的地方了

 

我开始找它这个字段是哪里来的:

用这个字段在网站源码里查找,很快就找到了

python爬虫破解带有RSA.js的RSA加密数据的反爬机制 Python 第3张

 

 

 源码:

        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暴露出来的对象

python爬虫破解带有RSA.js的RSA加密数据的反爬机制 Python 第4张

 

 

 

好的,这个放一边

 

encryptedString

 

这个函数也是RSA.js里的:

python爬虫破解带有RSA.js的RSA加密数据的反爬机制 Python 第5张

 

 

 

第三方js

再经过我的发现,其实还借用了BigInt.js和Barrettt.js

python爬虫破解带有RSA.js的RSA加密数据的反爬机制 Python 第6张

 

 

 

好的,有了眉目之后,将关键的代码放到本地测试,再经过我的调整,代码如下:

 

python爬虫破解带有RSA.js的RSA加密数据的反爬机制 Python 第7张

 

 

 

访问这个html文件,看控制台的输出:

python爬虫破解带有RSA.js的RSA加密数据的反爬机制 Python 第8张

 

 

 

发现成了,卧槽,我那个激动啊

 

然后用这个字段跟之前浏览器访问的对比:

python爬虫破解带有RSA.js的RSA加密数据的反爬机制 Python 第9张

 

 

 

反正长度是一样了,不知道对不对了,我还发现,每次运行得到的结果都是不一样的,不管那么多,直接复制新生成的去请求:
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:

 

python爬虫破解带有RSA.js的RSA加密数据的反爬机制 Python 第10张
/* 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; } 
RSA加密关键部分

 

好的,把那段js换成本地的,然后execjs执行js,然后得到封装到headers里就行了:

顺便再说一句,这里用js2py行不通,用execjs可行,我也不知道为啥,用js2py会直接在运行那段js代码的时候卡住,用execjs在几秒内就可以生成那段rsa_key

 

python爬虫破解带有RSA.js的RSA加密数据的反爬机制 Python 第12张
#!/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)
Python请求rsa加密的网站

 

 

 

理论上本篇文章是完了,其实这里还有一个坑,目前还不行,因为也是我的研究发现的,有朋友要问,为什么还不行,不是已经搞定了吗?真的还没有,这里还有一个大坑:

回到刚刚解析的RSA函数那里:

python爬虫破解带有RSA.js的RSA加密数据的反爬机制 Python 第14张

 

 根据我的研究,发现圈出区域的字段是会变的,玛德,你说这里是不是个大坑?不信?我f5刷新下,再看:

python爬虫破解带有RSA.js的RSA加密数据的反爬机制 Python 第15张

 

 

变量val变了,其他还有没有变目前无法得知,那么就得每次要爬取这个网站之前,先获取一次这个网站的源码,将这个RsaFunc重组一下:

python爬虫破解带有RSA.js的RSA加密数据的反爬机制 Python 第16张

 

 

完整代码:

python爬虫破解带有RSA.js的RSA加密数据的反爬机制 Python 第17张
#!/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,完毕!!

 

 

 

 

 

 

 

 

 

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