webqq登录协议分析

webqq登录协议分析

通过webqq接口,可以实现发送、接收qq消息。

1。首先调用:http://ptlogin2.qq.com/check?appid=1002101&uin=qq号码&js_ver=10034&js_type=0&login_sig=g3W6wI0s*Da9mp6xHYdgm7iP-D7LBMId01umPiT0WTQQShsmCdWxgBD8vtI6Gltq&u1=http%3A%2F%2Fweb.qq.com%2Fmain.shtml%3Fdirect_13_13&r=

获取该qq号码验证码之类的信息。看返回结果决定是不是要输入验证码登陆。

如果返回:ptui_checkVC('1','95ab7db15e5ab17f50f25d33598259e83ccc098c4af2f8a4');需要输入验证码,这里需要记住这个长字符串(获取验证码图片用)以及cookie
如果返回:ptui_checkVC('0','!MPG');不需要输入验证码,验证码值用!MPG代替。可能为其他字符串,但是以感叹号开头
如果需要输入验证码:则调用:
http://captcha.qq.com/getimage?aid=1002101&&uin= qq号码&r= 随机数
获取验证码图片。。。

2。开始登陆,在登陆之前,需要将密码进行hash,hash方法很复杂,但是研究其登录js文件,发现:

function getSubmitUrl(K) {
    var E = true;
    var C = document.forms[0];
    var A = (pt.isHttps ? "https://ssl.": "http://") + "ptlogin2." + g_domain + "/" + K + "?";
    var B = document.getElementById("login2qq");
    if (pt.regmaster == 2) {
        A = "http://ptlogin2.function.qq.com/" + K + "?regmaster=2&"
    } else {
        if (pt.regmaster == 3) {
            A = "http://ptlogin2.crm2.qq.com/" + K + "?regmaster=3&"
        }
    }
    for (var J = 0; J < C.length; J++) {
        if (K == "ptqrlogin" && (C[J].name == "u" || C[J].name == "p" || C[J].name == "verifycode" || C[J].name == "h")) {
            continue
        }
        if (C[J].name == "ipFlag" && !C[J].checked) {
            A += C[J].name + "=-1&";
            continue
        }
        if (C[J].name == "fp" || C[J].type == "submit") {
            continue
        }
        if (C[J].name == "ptredirect") {
            g_ptredirect = C[J].value
        }
        if (C[J].name == "low_login_enable" && (!C[J].checked)) {
            E = false;
            continue
        }
        if (C[J].name == "low_login_hour" && (!E)) {
            continue
        }
        if (C[J].name == "webqq_type" && !B && (!C[J].checked)) {
            continue
        }
        A += C[J].name;
        A += "=";
        if (C[J].name == "u" && pt.needAt) {
            A += pt.needAt + "&";
            continue
        }
        if (C[J].name == "p") {
            var M = C.p.value;
            var I = hexchar2bin(md5(M));
            var H = md5(I + pt.uin);		
            var G = md5(H + C.verifycode.value.toUpperCase());
            A += G
        } else {
            if (C[J].name == "u1" || C[J].name == "ep") {
                var D = C[J].value;
                var L = "";
                if (g_appid == "1003903" && B) {
                    L = /\?/g.test(D) ? "&": "?";
                    var F = document.getElementById("webqq_type").value;
                    L += "login2qq=" + B.value + "&webqq_type=" + F
                }
                A += encodeURIComponent(D + L)
            } else {
                A += C[J].value
            }
        }
        A += "&"
    }
    A += "fp=loginerroralert&action=" + pt.action.join("-") + "-" + (new Date() - g_begTime) + "&mibao_css=" + pt.mibao_css + "&t=" + pt.submitN[pt.uin] + "&g=1";
    A += "&js_type=" + pt.js_type + "&js_ver=" + window.g_pt_version + "&login_sig=" + window.g_login_sig;
    return A
}
其中的:

        if (C[J].name == "p") {
            var M = C.p.value;
            var I = hexchar2bin(md5(M));
            var H = md5(I + pt.uin);		
            var G = md5(H + C.verifycode.value.toUpperCase());
            A += G
便是其hash方法,研究发现其md5与python md5是一致的(对于c#貌似两者计算的md5有区别)

对于hexchar2bin函数,可以使用参考其js代码写出相应的python版本:

	def hexchar2bin(self,str):
		arr = []
		for i in range(0, len(str) , 2):
			arr.append("\\x" + str[i:i+2])
		arr="".join(arr)
		exec("temp = '" + arr + "'");
		return temp

3、正式登录:
url = self.scheme + "ptlogin2.qq.com/login?u=" + self.qq + "&p=" + p + "&verifycode=" + VERIFYCODE + "&webqq_type=1&remember_uin=1&aid=1002101&u1=http%3A%2F%2Fweb.qq.com%2Fmain.shtml%3Fdirect_13_13&h=1&ptredirect=1&ptlang=2052&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=7-31-419619&mibao_css=&t=2&g=1&js_type=0&js_ver=10034"

登陆成功后,要记住返回的cookie值(其中的ptwebqq在之后需要使用)


正式登录web QQ:

url = 'http://d.web2.qq.com/channel/login2'
		
header={'Referer':'http://d.web2.qq.com/proxy.html?v=20110331002&callback=1&id=2'}
POST的data包含:ptwebqq,clientid等参数

如果成功:
会返回一个json数据结构:
{"retcode":0,"result":{"uin":qq号 码,"mode":"master","index":1055,"port":38138,"status":"online","vfwebqq":"f72a8722c988252aef4e0268f1d26a3d647f06f6ff353a5c6cdaaa49abb2fcdf0cee2d8d64373ac2","psessionid":"8368046764001D636F6E6E7365727665725F77656271714031302E3133332E332E3234300000235100000B79026E040043F60C166D0000000A404746365677767041316D00000028F72A8722C988252AEF4E0268F1D26A3D647F06F6FF353A5C6CDAAA49ABB2FCDF0CEE2D8D64373AC2"}}
记住其中的psessionid以及vfwebqq,后面在发送消息和获取qq消息都需要这2个参数。




你可能感兴趣的:(webqq登录协议分析)