Packet Capture analysis
Get Verification Code
Get encrypted public key
Where the hash is changed, the public key key remains unchanged
Login
Where the user name is not encrypted and the password is encrypted.
Because a hash value is returned at the same time when the public key is obtained, it is assumed that the hash value is related to password encryption.
Analyze JS code via Google Chrome Console
Right-click the login button, check, view the Event Listeners, a.btn.btn-login the right side of the login.4f030c3....js:6 to view the JS code.
Click {} in the lower left corner to expand the code
Because there is action=getkey in the link to get the public key and hash, try to search for Getkey in the source code, then find such a function:
1Encryptpassword:function(E, t) {2 varn = This,3r =!1;4 return$.ajax ({5URL: "https://passport.bilibili.com/login?act=getkey&r=" +math.random (),6Async:!17}). Done (function(t) {8T && t.error && (n.publictip = "Login failed, server exception occurred", E =NULL);9 vari =NewJsencrypt;Ten I.setpublickey (t.key); One varA = I.encrypt (T.hash +e); AE =A, -r =!0 - }), theR? E: "" -}
Observing the 10th and 11 lines, we know that the hash and the variable e are encrypted by RSA and now need to determine what E is. Set a breakpoint at the location of the 11th line of code, enter the user name password verification code and click Login, here the Password box input is ' MyPassword '
Click E to display the value of E, it appears that E is the password plaintext.
Therefore, it can be guessed that the process of encryption is: the password string is preceded by string hash value, and then RSA encryption. The following test checks to see if the guesses are correct.
Analog Login
The headers of each request completely replicates the contents of the capture package.
1. Get the Verification code
1 defGet_code ():2Url='https://passport.bilibili.com/captcha?r=0.1265352187487443'3headers={Copy the headers} to which the packet was caught4 session.headers.clear ()5 session.headers.update (Headers)6R=session.get (URL)7File=open ('code.jpg','WB')8 file.write (r.content)9File.close ()
2.getkey
1 defGet_key ():2Url='https://passport.bilibili.com/login?act=getkey&r=0.4365052982637341'3headers={Copy the headers} to which the packet was caught4 session.headers.clear ()5 session.headers.update (Headers)6R=session.get (URL)7Jsondata=json.loads (R.text)8 #hash change, key unchanged9 return(jsondata['Hash'],jsondata['Key'])
3. Encryption, refer to the appendix of the demo login of the blog Park
1 defEncrypt (Hash,key,password):2 fromCrypto.publickeyImportRSA3 fromCrypto.cipherImportpkcs1_v1_54 fromBase64ImportB64encode5Encryptor=pkcs1_v1_5.new (Rsa.importkey (bytes (Key,'Utf-8')))6 returnSTR (b64encode (encryptor.encrypt (bytes (Hash+password,'Utf-8'))),'Utf-8')
4. Login
1 defLogin (Code,username,password):2 #Note that the verification code will automatically be capitalized in the login page3Url='Https://passport.bilibili.com/web/login'4headers={Copy the headers} to which the packet was caught5data={'CType':'2',6 'Vctype':'1',7 'Captcha': Code,8 'User': Username,9 'pwd':p Assword,Ten 'Keep':'true', One 'Gourl':'http://www.bilibili.com/'} A session.headers.clear () - session.headers.update (Headers) -R=session.post (url,data=data) the returnR.text
If the login succeeds, it will return "code": 0
5. Testing
Testurl='https://www.bilibili.com/account/dynamic'
When not logged in, the title of Testurl is "bilibili-hint", log in with the title "Beep @@facesymbol@@つロ Cheers ~-bilibili"
session.headers.clear () r=session.get (testurl) P=r.text.find ('<title> ') +len ('<title>')print(r.text[p:r.text.find (' <', p)])
Impersonate a login in Python using the request Library (iv): Beep (encrypted, with verification code)