VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • python爬虫破解带有RSA.js的RSA加密数据的反爬机制

前言

 

同上一篇的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复制出来吗?想想这样繁琐不?

 

因为都知道,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