def test_rsa_encryption(self): # TODO: test string which its length is larger than 126 (a chunk size in Baidu's case) cases = ( ('tetetetetetetetetetetetetetetetete', '617758987d012eb47b4b61498472e2d3ae96f891512bf130c6b42d724ec81b21f6e9cbbbc17cf2f260b5c76feaebc99615f5df5c5a88ddf4b859c0dbf1daba476af4f55f4502a0ce84e6adcf397909a9933f093be08381ac2ceb4b1e4d48f2e5eb87fdac2f259bc3b85cd674a0c9ef2e8b3debba1043c7af8ab378db0123463e'), ('testdata', '1d49d809c48d14444cd0bcd739f50a86fee8df6a6c3c73ffd57c55c0124c89816b2e3d7a8d5ffd1d5d1ba5fac092590ad20be7b3a3c22284074027f4b99af04fc98ffebe5a82ae161675fd7bfbe6f54c3d3425465d62c9cff013ea861f5a6c222fd735e92c0d4acda0b0a103a83f45b1a7d2bfd2458501b89ca4c08d61715af3') ) for string, result in cases: self.assertEqual(crypto.rsa_encrypt(string, RSA_MODULUS, RSA_PUB_KEY), result)
def login(cls, username, password): s = requests.Session() # 随便访问一个网址来获得一个 SESSION ID (BAIDUID) # 否则会提示你 请开启 Cookie s.get('http://wappass.baidu.com/passport/?login') timestamp = str(int(time.time())) # 当前时间 精确到秒 server_time = s.get('http://wappass.baidu.com/wp/api/security/antireplaytoken?tpl=wimn&v={time}'.format(time=timestamp)).json()['time'] payload = { 'loginmerge': '1', 'servertime': server_time, 'username': username, 'password': rsa_encrypt(password + server_time, RSA_MODULUS, RSA_PUB_KEY), 'gid': 'ED9E656-A818-402B-9E18-7D4349C9E86F' # 随便取 } r = s.post('https://wappass.baidu.com/wp/api/login?tt={}'.format(timestamp), data=payload) # 是否需要验证码 vcodestr = r.json()['data']['codeString'] if vcodestr: while True: r_captcha = s.get('https://wappass.baidu.com/cgi-bin/genimage?{0}&v={1}'.format(vcodestr, timestamp), stream=True) captcha = Captcha(r_captcha.raw) user_input = yield captcha if user_input is not None: # 支持两种方式填验证码: # 1. captcha.fill(somecaptcha) # 2. gen.send(somecaptcha) # 如果都填有,优先采用第二种 captcha.fill(user_input) if captcha.input is None: raise InvalidCaptcha(500002, 'You have typed an incorrect captcha') elif captcha.input == 'another': continue else: break timestamp = str(int(time.time())) # 重新获取时间 server_time = s.get('http://wappass.baidu.com/wp/api/security/antireplaytoken?tpl=wimn&v={time}'.format(time=timestamp)).json()['time'] payload['vcodestr'] = vcodestr payload['servertime'] = server_time payload['verifycode'] = user_input payload['password'] = rsa_encrypt(password + server_time, RSA_MODULUS, RSA_PUB_KEY) # 因为密文跟时间捆绑,需一起重新获取 r = s.post('https://wappass.baidu.com/wp/api/login?tt={}'.format(timestamp), data=payload) data = r.json() status = data['errInfo']['no'] message = data['errInfo']['msg'] if status == '0': yield cls(data['data']['bduss']) elif status == '400011': raise InvalidPassword(400011, message) elif status == '500002': raise InvalidCaptcha(500002, message) elif status == '50000': raise DangerousEnvironment(50000, message) elif status == '400010' or status == '230048': # 400010 用户不存在 # 230048 用户名格式错误 raise InvalidUsername(int(status), message) elif status == '400101': raise LoginFailure(400101, 'Email auth required. Use BDUSS instead.') else: raise LoginFailure(status, message)