我测试的qq空间的登陆页面http://qzone.qq.com/,打开浏览器调试工具,然后qq号和密码随便写,提交请求的时候就能看到是一个http/get请求,是一个js发出去的。 b1.png 将这个js下载下来,然后格式化一下代码。在http://paste.ubuntu.org.cn/1873103备份一个,蛋疼的github gitst貌似被墙了。 里面有个这样的函数

getSubmitUrl: function(b) {
        var a = pt.plogin.loginUrl + b + "?";
        var f = {};
        if (b == "login") {
            f.u = encodeURIComponent(pt.plogin.at_accout);
            f.verifycode = $("verifycode").value;
            if (pt.plogin.needShowNewVc) {
                f.pt_vcode_v1 = 1
            } else {
                f.pt_vcode_v1 = 0
            }
            f.pt_verifysession_v1 = pt.plogin.pt_verifysession || $.cookie.get("verifysession");
            var d = $("p").value;
            if (pt.plogin.armSafeEdit.isSafe) {
                d = pt.plogin.armSafeEdit.safepwd
            }
            if (pt.plogin.RSAKey) {
                f.p = $.Encryption.getRSAEncryption(d, f.verifycode, pt.plogin.armSafeEdit.isSafe);
                f.pt_rsa = 1
            } else {
                f.p = $.Encryption.getEncryption(d, pt.plogin.saltUin, f.verifycode, pt.plogin.armSafeEdit.isSafe);
                f.pt_rsa = 0
            }
        }

其中调用的加密函数是这样的

$.Encryption = function() {
    var hexcase = 1;
    var b64pad = "";
    var chrsz = 8;
    var mode = 32;
    //省略一些密码算法 主要是md5和base64算法
    function getEncryption(password, uin, vcode, isMd5) {
        var str1 = hexchar2bin(isMd5 ? password: md5(password));
        var str2 = md5(str1 + uin);
        var str3 = md5(str2 + vcode.toUpperCase());
        return str3
    }
    function getRSAEncryption(password, vcode, isMd5) {
        var str1 = isMd5 ? password: md5(password);
        var str2 = str1 + vcode.toUpperCase();
        var str3 = $.RSA.rsa_encrypt(str2);
        return str3
    }
    return {
        getEncryption: getEncryption,
        getRSAEncryption: getRSAEncryption
    }
} ();

上面的那个getSubmitUrl方法主要就是拼接登陆用的url,其中就要带上密码。可以发现密码并不是明文传输的,而且是有两种不同的算法,一个是RSA,一个是md5。

这样大致的思路有了以后就可以直接去调试了,使用firebug在相关的语句上都下断点,果然进入了md5加密的函数。 b2.png b3.png 注意看右边,最终产生的str3的值。 然后加在了url中 p4.png

总结一下,我们这一次登陆的时候的密码加密方法是 md5(md5(md5(密码) + uin) + 随机token)

但是重点还不是在这里,想一下,腾讯的服务器怎么验证密码是否正确呢?

首先随机token和uin肯定是知道的,一个应该在session中,一个就是用户qq号,然后重点是md5(md5(密码) + uin)了。 这个很容易就能想出来吧,只要服务器知道以下信息之一,就能检验密码是否正确。

而那些进行了其他的非md5的加密或者使用md5多次加密或者使用md5+salt加密都会导致没办法进行当前方式的验证了。所以我的猜想就是腾讯的服务器存储密码的方法无非就是上面的三种方式或者三种方式的可逆加密。