利用HttpFox监视并且分析所有进出浏览器的HTTP网络传输。HttpFox是FireFox浏览器的一个插件,监视Http网络数据传输很方便。请求的数据包括:
(1) 请求和响应头数据
(2) 发送和接收的Cookie
(3) 查询Query的各项参数
(4) POST的参数和数据
(5) 响应Body数据
(6) ......
监视新浪微博登录时和服务器的数据传输情况。如图1所示
图 1 登录新浪微博Http网络传输数据
(1) 分析登录过程,在提交POST请求之前,进行了两次GET请求,第二次GET请根据浏览器的不同传递不同数据,没意义。如图1第一次GET请求地址是:http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=c3dqdHV6dyU0MGdtYWlsLmNvbQ%3D%3D&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.5)&_=1370244920303
如图5-1下部分。得知返回数据:sinaSSOController.preloginCallBack({"retcode":0,"servertime":1370244920,"pcid":
"xd-fec4e580e9a32b605d0027a0269d765d05a9","nonce":"IFO817","pubkey":
"EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443","rsakv":"1330428213","showpin":0,"exectime":8})
整理数据如表1 所示
表1 第一个GET请求返回数据
参数名
值
retcode
0
servertime
1370244920
pcid
xd-fec4e580e9a32b605d0027a0269d765d05a9
nonce
IFO817
pubkey
EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E
7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFF
B38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6
442443
rsakv
1330428213
showpin
0
exectime
8
经查询资料,表1中有两个重要参数“servertime”和“nonce”,其他为固定值。
(2) 观察POST请求:
如图5-2所示可知POST请求的数据包括的一些信息。
图2 POST数据包参数和值
其中“su”为用户名,它经过BASE64计算。“sp”为密码,其加密方法为:
先创建一个rsa公钥,公钥的两个参数新浪微博都给了固定值,不过给的都是16进制的字符串,第一个是登录第一步中的pubkey(见表1),第二个是js加密文件中的‘10001’。这两个值需要先从16进制转换成10进制。然后再servertime加上nonce加上用户密码进行RSA加密。
(3) 模拟登录
通过研究新浪微博登录的过程,就可以伪造一个HttpClient实例进行登录了。
①构造一个HttpClient实例:
DefaultHttpClient client = new DefaultHttpClient();
②构造第一个登录请求:获取servertime和nonce的值。
③对用户名和密码进行加密
String pwdString = servertime + "t" + nonce +"n" + "pwd";
sp = new BigIntegerRSA().rsaCrypt(SINA_PK,"10001",pwdString);
④构造POST数据包。
HttpPost post = new HttpPost( "http://login.sina.com.cn/sso/login.php?client=ssologin.js (v1.4.2)");
……
post.setEntity(newUrlEncodedFormEntity(nvps, HTTP.UTF_8)); ①
⑤执行POST请求。
HttpResponse response=null;
……
response= client.execute(post);
⑥获取实际URL,并请求该URL。
String entity=null;

……
entity =EntityUtils.toString(response.getEntity());
……
String url =entity.substring(
entity.indexOf("http://weibo.com/sso/login.php?"),
entity.indexOf("code=0")+ 6); // 获取到实际url进行连接
HttpGet getMethod= new HttpGet(url);
……
response =client.execute(getMethod);
⑦获取Cookie。
CookieStore cookie = client.getCookieStore();
通过以上步骤模拟登录就处理完了,可以通过最后获取的Cookie信息进行新浪微博页面的访问,只需要在请求页面的时候将此Cookie发送过去身份认证就完成了。通过身份认证就可以对新浪微博的页面进行访问了。