Skip to content

Instantly share code, notes, and snippets.

@littleblacklb
Last active November 6, 2022 07:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save littleblacklb/269ecb76811ff20d3dfb3cea2cf5b1a4 to your computer and use it in GitHub Desktop.
Save littleblacklb/269ecb76811ff20d3dfb3cea2cf5b1a4 to your computer and use it in GitHub Desktop.
B站密码登录方式获取Cookie实例
"""
FilePath : /src/BiliLogin.py
Author : littleblackLB
Date : 2022-07-19 22:50:47
LastEditTime : 2022-11-06 14:54:55
"""
"""
Bili Account Login
Reference: https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/login/login_action/password.md
"""
import base64
import hashlib
import json
import time
import urllib.parse
import requests
import rsa
# Android Platform
APP_KEY = "1d8b6e7d45233436"
APP_SECERT = "560c52ccd288fed045859ed18bffd973"
BUILD_NUMBER = 5520400
session = requests.session()
session.headers = {
'Referer': 'http://www.bilibili.com/',
'Content-Type': 'application/x-www-form-urlencoded',
}
def get_time():
return str(int(time.time()))
def url_encode(s: str):
return urllib.parse.quote_plus(s)
def get_url_param():
parameters = dict()
parameters["build"] = BUILD_NUMBER
parameters["appkey"] = APP_KEY
parameters["mobi_app"] = "android"
parameters["platform"] = "android"
parameters["ts"] = get_time()
param = ""
for key in parameters.keys():
param += "{}={}&".format(key, parameters[key])
param = param[:len(param) - 1]
param += "&sign={}".format(get_sign(param))
return param
def get_sign(param: str):
param_list = param.split("&")
param_list.sort()
s = ""
for p in param_list:
s += p + '&'
s = s[:len(s) - 1] # Remove the last ampersand
s += APP_SECERT
hl = hashlib.md5()
hl.update(s.encode())
return hl.hexdigest().lower()
def post(url, param):
global session
r = session.post(url, data=param)
return r
def get(url):
global session
r = session.get(url=url)
return r
def get_hash():
# return post("https://passport.bilibili.com/api/oauth2/getKey", get_url_param()).text
return get('https://passport.bilibili.com/x/passport-login/web/key').text
def encrypt_password(pwd: str):
param = get_url_param()
hash_json_obj = json.loads(get_hash())
hs = hash_json_obj["data"]["hash"]
key = hash_json_obj["data"]["key"]
print("Public RSA Key:")
print(key)
pwd = hs + pwd # Add salt
# re_rsa = re.compile("-----BEGIN PUBLIC KEY-----([\\s\\S]+)-----END PUBLIC KEY-----")
# key = re_rsa.match(key).groups()[0]
# key = key.replace("\n", "")
"""
# Old:
rsakey = RSA.importKey(key)
cipher = Cipher_pkcs1_v1_5.new(rsakey)
enc_pwd = base64.b64encode(cipher.encrypt(pwd.encode())).decode()
"""
pub_key = rsa.PublicKey.load_pkcs1_openssl_pem(key) # 读取 PEM 密钥
enc_pwd = base64.b64encode(rsa.encrypt(pwd.encode(), pub_key)).decode()
return enc_pwd, hs
# Old unavailable version:
# def login(uname, pwd, token, challenge, validate, seccode):
# # http://passport.bilibili.com/web/login/v2
# pwd, key = encryptPassword(pwd)
# # param = "appkey={}&build={}&mobi_app=android&password={}&platform=android&ts={}&username={}".format(
# # APP_KEY, BUILD_NUMBER, url_encode(pwd), get_time(), uname
# # )
# param = "captchaType=6&username={}&password={}&keep=true&key={}&challenge={}&validate={}&seccode={}".format(
# uname,
# url_encode(pwd),
# # pwd,
# token,
# challenge,
# validate,
# seccode
# )
# # param += "&sign=" + getSign(param)
# print("\nparam: ", param)
# r = post("http://passport.bilibili.com/web/login/v2", param)
# text = r.text
# print(text)
# print(r.cookies)
def login(uname, pwd, token, challenge, validate, seccode):
print("######Stage: Get Initial Cookie######")
get("http://www.bilibili.com") # Get Cookie
for k in session.cookies:
print(k)
print("######End######")
print()
print("######Stage: Encrypt Password######")
# http://passport.bilibili.com/x/passport-login/web/login
pwd, key = encrypt_password(pwd) # Print PubKey inside function
print("Encoded password: ", pwd)
print("######End######")
print()
print("######Stage: Construct Parameters######")
param = "username={}&password={}&keep=true&token={}&challenge={}&validate={}&seccode={}".format(
url_encode(uname),
url_encode(pwd),
url_encode(token),
url_encode(challenge),
url_encode(validate),
url_encode(seccode)
)
print("Params: ", param)
print("######End######")
print()
print("######Stage: Try To Login######")
r = post("http://passport.bilibili.com/x/passport-login/web/login", param)
print("Response Content:")
print(r.text)
print("Cookies:")
for k in session.cookies:
print(k)
print("######End######")
def fetch_verification_params():
global session
url = "https://passport.bilibili.com/x/passport-login/captcha?source=main_web"
data_obj = json.loads(session.get(url).text)["data"]
challenge = data_obj["geetest"]["challenge"]
gt = data_obj["geetest"]["gt"]
token = data_obj["token"]
return challenge, gt, token
if __name__ == '__main__':
phone_num = input("tel. number=")
org_pwd = input("pwd=")
# https://passport.bilibili.com/x/passport-login/captcha?source=main_web
cge, gt, token = fetch_verification_params()
print(token)
print("challenge:", cge, "gt:", gt)
print("https://kuresaru.github.io/geetest-validator/")
vad = input("validate=")
sec_code = vad + "|jordan"
print()
login(phone_num, org_pwd, token=token, challenge=cge, validate=vad, seccode=sec_code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment