百度登录算法分析和实现(上 - 分析篇)

分析工具:IE10、HttpWatch

密码算法:RSA

难        度:★★☆☆☆


分析步骤:

①、打开IE,打开httpwatch,老规矩 Clean cache and all cookies,开启抓包,然后打开百度首页:http://www.baidu.com/,什么都不用管,直接登录,登录完成后所有的包都有了。


②、包有了,开始搞吧,我们先看看最后的登录包:

看看里面有几个像是动态参数:gid、password、rsakey、token、tt,字面意思和值告诉我们,gid - 未知, password - 加密后的密码, rsakey - rsa key,token - 登录令牌,tt - 时间戳,分析大致的意思让分析思路更加明确,像这个tt我们基本不用管了。


、我们先来找gid的值,复制gid的值在httpWatch里面搜索,看看在服务器返回Cookies里面有没有,结果……并没有,所以这个值可能就是在客户端生成的了,那就直接搜索gid=,来到一处:https://ss0.bdstatic.com/5LMZfyabBhJ3otebn9fN2DJv/passApi/js/uni_login_tangram_6601c89c.js ,看看里面的代码:


function() {
                var z = document.location.protocol.toLowerCase();
                var x = u.guideRandom ? u.guideRandom: "";
                if (z == "http:") {
                    var y = "http://nsclick.baidu.com/v.gif?pid=111&url=&logintype=hide&merge=1&gid=" + x + "&tpl=" + l.apiOpt.tpl + "&tt=" + new Date().getTime()
                } else {
                    if (z == "https:") {
                        var y = "https://passport.baidu.com/img/v.gif?cdnversion=60706311.gif?pid=111&url=&logintype=hide&merge=1&gid=" + x + "&tpl=" + l.apiOpt.tpl + "&tt=" + new Date().getTime()
                    }
         }



通过这个JS我们不难看出这个值来自:u.guideRandom,不管他,直接搜 guideRandom,找到了好几处,我们的目的很明确,找到他实现的地方,直到看到一个 this.guideRandom=(function() 就说明就是这个了,在这个JS里面:https://ss0.bdstatic.com/5LMZfyabBhJ3otebn9fN2DJv/passApi/js/login_0a0d41f2.js ,这个JS 是utf8的,我们先选一下格式utf-8,然后复制整个js出来,找个JS在线格式化工具格式化一下,粘贴到notepad++里面,这样就比较好看了,找到实现:


this.guideRandom = (function() {
            return "xxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,
            function(c) {
                var r = Math.random() * 16 | 0,
                v = c == "x" ? r: (r & 3 | 8);
                return v.toString(16)
            }).toUpperCase()
        })();


原来是个大忽悠,,这个值是随机的,并且没有任何动态参数参与运算,我们整理一下,不管他虽不随机,我们保留吧:


function guid_random()
	{
		return "xxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,
		function(c) {
			var r = Math.random() * 16 | 0,
			v = c == "x" ? r: (r & 3 | 8);
			return v.toString(16)
		}).toUpperCase();
	}



好了,继续下一个参数,password,直接搜索&password发现找不到,那就找找 password= 吧,还是定位 login_0a0d41f2.js ,我们看下关键代码:


submit: function() {
            var me = this;
            if (me.internation && !me._validatorforeignmobileFn(me.getElement("foreignMobile"))) {
                return
            }
            me.validateAll({
                success: function() {
                    me._doFocus("submit");
                    me.submitStatus = 1;
                    var returnValue = me.fireEvent("beforeSubmit");
                    me.getElement("submit").style.color = "#9ebef4";
                    if (!returnValue) {
                        return
                    }
                    if (me.spLogin) {
                        var usernameTemp = baidu('<input type="hidden" name="splogin" value="' + me.spLogin + '">');
                        me.getElement("hiddenFields").appendChild(usernameTemp.get(0));
                        me.spLogin = null
                    }
                    var data = baidu.form.json(me.getElement("form"));
                    data.token = me.bdPsWtoken;
                    passport.data.setContext(baidu.extend({},
                    me.config));
                    if (me.RSA && me.rsakey) {
                        var passwordVal = me.getElement("password").value;
                        if (passwordVal.length < 128 && !me.config.safeFlag) {
                            data.password = baidu.url.escapeSymbol(me.RSA.encrypt(passwordVal));
                            data.rsakey = me.rsakey;
                            data.crypttype = 12
                        }
                    }
                    var submitEle = me.getElement("submit"),
                    time = 15000,
                    submitInterval;
                    me.getElement("submit").style.color = "#9ebef4";
                    submitEle.value = me.lang.logining;
                    submitInterval = setTimeout(function() {
                        if (me.submitStatus === 1 && !me.config.connect) {
                            me.setGeneralError(me.lang.submitTimeup)
                        }
                        submitEle.value = me.lang.login
                    },
                    time);
                    function loginFn() {
                        data.timeSpan = new Date().getTime() - me.initTime;
                        if (me.internation) {
                            data.username = me.getElement("foreignMobile").value;
                            data.isPhone = true;
                            data.countrycode = baidu(me.getElement("foreignMobileLabel")).attr("data-countrycode") || ""
                        } else {
                            data.countrycode = ""
                        }
                        passport.data.login(data).success(function(rsp) {
                            me.submitStatus = 2;
                            if (rsp.errInfo.no == 0) {
                                var returnValue = me.fireEvent("loginSuccess", {
                                    rsp: rsp
                                });
                                if (!returnValue) {
                                    return
                                }
                                if (window.location) {
                                    window.location.href = rsp.data.u
                                } else {
                                    document.location.href = rsp.data.u
                                }
                            } else {
                                submitEle.value = me.lang.login;
                                me.getElement("submit").style.color = "#fff";
                                var returnValue = me.fireEvent("loginError", {
                                    rsp: rsp
                                });
                                if (!returnValue) {
                                    return
                                }
                                me._defaultLoginErr(rsp)
                            }
                        })
                    }
                    me.loginConnect({
                        username: data.userName,
                        password: data.password
                    },
                    {
                        success: function() {
                            clearTimeout(submitInterval);
                            submitEle.value = me.lang.login
                        },
                        fail: function(msg) {
                            clearTimeout(submitInterval);
                            submitEle.value = me.lang.login;
                            me.setGeneralError(msg)
                        }
                    },
                    loginFn)
                }
            },
            true)
        }

看到这个基本就是一目了然了吧:

       data.password = baidu.url.escapeSymbol(me.RSA.encrypt(passwordVal));
                            data.rsakey = me.rsakey;
                            data.crypttype = 12


我们要提交的数据都在这个data里,我们的密码就是通过RSA一层之后escapeSymbol ,找RSA简单了,我们主要是找到RSA起始和结束点,提取出来,整理成一个函数。


rsakey我们搜索一下就能找到:https://passport.baidu.com/v2/getpublickey?token=fcd1f6684072372c6812a44c1d94bf51&tpl=mn&apiver=v3&tt=1461222170065&gid=C539A37-9B0C-4538-9920-E150AC6AE0D5&callback=bd__cbs__tpdrlq 返回的,而这个URL中也有个token,所以现在只要找到 token ,所有的问题就迎刃而解了,我们搜一下token的值,在https://passport.baidu.com/v2/api/?getapi&tpl=mn&apiver=v3&tt=1461222159011&class=login&gid=C539A37-9B0C-4538-9920-E150AC6AE0D5&logintype=dialogLogin&callback=bd__cbs__jcbr21 里面找到了,是服务器返回的。


这样一来所有的参数都已经找到了,下篇文章我们来模拟整个登录过程。


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值