在Python中用Request库模拟登录(四):哔哩哔哩(有加密,有验证码)

 !已失效!

抓包分析

获取验证码

获取加密公钥

其中hash是变化的,公钥key不变

登录

其中用户名没有被加密,密码被加密。

因为在获取公钥的时候同时返回了一个hash值,推测此hash值与密码加密有关。

通过谷歌浏览器控制台分析js代码

 右键登录按钮,检查,查看 Event Listeners ,点击a.btn.btn-login右边的login.4f030c3....js:6查看js代码。

点击左下角的{}展开代码

因为获取公钥和hash的链接中有action=getkey,尝试在源代码中搜索getkey,于是找到这样一个函数:

 1 encryptPassword: function (e, t) {
 2     var n = this,
 3     r = !1;
 4     return $.ajax({
 5         url: "https://passport.bilibili.com/login?act=getkey&r=" + Math.random(),
 6         async: !1
 7     }).done(function (t) {
 8         t && t.error && (n.publicTip = "登录失败,服务端出现异常", e = null);
 9         var i = new JSEncrypt;
10         i.setPublicKey(t.key);
11         var a = i.encrypt(t.hash + e);
12         e = a,
13         r = !0
14     }),
15     r ? e : ""
16 }

 观察第10、11行,可知hash和变量e相加后被RSA加密,现在需要确定e是什么。在第11行代码所在的位置设置一个断点,输入用户名密码验证码之后点击登录,在这里密码框输入的是‘mypassword’

点击e就会显示出e的值,看来e就是密码明文。

于是,可以猜测,加密的过程是:密码字符串前面串接hash值,然后进行RSA加密。下面通过测试检查猜测是否正确。

模拟登录

每一次请求的headers都完全复制抓包的内容。

1.获取验证码

1 def get_code():
2     url='https://passport.bilibili.com/captcha?r=0.1265352187487443'
3     headers={复制抓包到的headers}
4     session.headers.clear()
5     session.headers.update(headers)
6     r=session.get(url)
7     file=open('code.jpg','wb')
8     file.write(r.content)
9     file.close()

2.getkey

1 def get_key():
2     url='https://passport.bilibili.com/login?act=getkey&r=0.4365052982637341'
3     headers={复制抓包到的headers}
4     session.headers.clear()
5     session.headers.update(headers)
6     r=session.get(url)
7     jsondata=json.loads(r.text)
8     #hash变化,key不变
9     return (jsondata['hash'],jsondata['key'])

3.加密,具体可以参考博客园的模拟登录的附录部分

1 def encrypt(Hash,key,password):
2     from Crypto.PublicKey import RSA
3     from Crypto.Cipher import PKCS1_v1_5
4     from base64 import b64encode
5     encryptor=PKCS1_v1_5.new(RSA.importKey(bytes(key,'utf-8')))
6     return str(b64encode(encryptor.encrypt(bytes(Hash+password,'utf-8'))),'utf-8')

4.登录

 1 def login(code,username,password):
 2     #注意,在登录页面中验证码会自动转成大写
 3     url='https://passport.bilibili.com/web/login'
 4     headers={复制抓包到的headers}
 5     data={'cType':'2',
 6           'vcType':'1',
 7           'captcha':code,
 8           'user':username,
 9           'pwd':password,
10           'keep':'true',
11           'gourl':'http://www.bilibili.com/'}
12     session.headers.clear()
13     session.headers.update(headers)
14     r=session.post(url,data=data)
15     return r.text

如果登录成功,将返回 "code":0

5.测试

testurl='https://www.bilibili.com/account/dynamic'

在未登录时,testurl的标题为“bilibili - 提示”,登录时标题为“哔哩哔哩 (゜-゜)つロ 干杯~-bilibili”

session.headers.clear()
r=session.get(testurl)
p=r.text.find('<title>')+len('<title>')
print(r.text[p:r.text.find('<',p)])

转载于:https://www.cnblogs.com/-E6-/p/6953590.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值