def t144( cls, imei: bytes, bootloader: str, proc_version: str, codename: str, incremental: str, fingerprint: str, boot_id: str, android_id: str, baseband: str, inner_version: str, os_type: bytes, os_version: bytes, network_type: int, sim_info: bytes, apn: bytes, is_guid_from_file_null: bool, is_guid_available: bool, is_guid_changed: bool, guid_flag: int, build_model: bytes, guid: bytes, build_brand: bytes, tgtgt_key: bytes, ) -> "Packet[()]": return cls._pack_tlv( 0x144, qqtea_encrypt( bytes( Packet.build( struct.pack(">H", 5), # tlv count cls.t109(imei), cls.t52d( bootloader, proc_version, codename, incremental, fingerprint, boot_id, android_id, baseband, inner_version, ), cls.t124(os_type, os_version, network_type, sim_info, apn), cls.t128( is_guid_from_file_null, is_guid_available, is_guid_changed, guid_flag, build_model, guid, build_brand, ), cls.t16e(build_model), )), tgtgt_key, ), )
def build( cls, uin: int, seq: int, command_name: str, session_id: bytes, body_type: int, body: Union[bytes, Packet], key: bytes, extra_data: bytes = b"", ) -> "UniPacket": data = Packet().write_with_length( struct.pack(">I", len(command_name) + 4), command_name.encode(), struct.pack(">I", len(session_id) + 4), session_id, struct.pack(">I", len(extra_data) + 4), extra_data, offset=4, ) data.write_with_length(body, offset=4) return cls().write_with_length( struct.pack(">IBIB", 0xB, body_type, seq, 0), struct.pack(">I", len(str(uin)) + 4), str(uin).encode(), qqtea_encrypt(bytes(data), key), offset=4, )
def test_qqtea_encrypt_n(n): seed(114514) for i in range(32): key, text = randbytes(16), randbytes(n) assert pyqqtea_encrypt(text, key) == qqtea_encrypt(text, key), f"in round {i}"
def build( cls, uin: int, body_type: int, body: Union[bytes, Packet], ksso_version: int = 0xA, key: Optional[bytes] = None, extra_data: bytes = b"", ) -> "CSsoDataPacket": """Build CSSOPacket head and append body. Packet body was encrypted in `CSSOData::serialize`. Note: Source: `CSSOHead::serialize_verFull` """ return cls().write_with_length( Packet.build( struct.pack(">IB", ksso_version, body_type), struct.pack(">I", len(extra_data) + 4), extra_data, bytes([0]), struct.pack(">I", len(str(uin)) + 4), str(uin).encode(), qqtea_encrypt(bytes(body), key) if key else body, ), offset=4, )
def encrypt( self, data: Union[bytes, Packet], key: Union[bytes, Packet] ) -> Packet: return Packet.build( struct.pack(">H", len(self.ticket)), self.ticket, qqtea_encrypt(bytes(data), bytes(key)), )
def test_qqtea_decrypt4096(benchmark): key, text = b"\xff" * 16, b"\xff" * 4096 cipher_text = qqtea_encrypt(text, key) def func(key, cipher_text): qqtea_decrypt(cipher_text, key) benchmark(func, key, cipher_text)
def test_qqtea_mixed_n(n): seed(114514) for i in range(32): key, text = randbytes(16), randbytes(n) cipher_text = qqtea_encrypt(text, key) assert pyqqtea_decrypt(cipher_text, key) == qqtea_decrypt(cipher_text, key), f"in round {i}" cipher_text = pyqqtea_encrypt(text, key) assert pyqqtea_decrypt(cipher_text, key) == qqtea_decrypt(cipher_text, key), f"in round {i}"
def t106( cls, sso_version: int, app_id: int, sub_app_id: int, app_client_version: int, uin: int, salt: int, password_md5: bytes, guid: bytes, tgtgt_key: bytes, ip: bytes = bytes(4), save_password: bool = True, login_type: int = 1, # password login ) -> "Packet[()]": key = md5( Packet.build(password_md5, bytes(4), struct.pack(">I", salt or uin))).digest() body = Packet.build( struct.pack( ">HIIIIQ", 4, # tgtgt version cls._random_int32(), sso_version, app_id, app_client_version, uin or salt, ), struct.pack(">I", int(time.time())), ip, struct.pack(">?", save_password), struct.pack(">16s", password_md5), tgtgt_key, struct.pack(">I?", 0, bool(guid)), guid or struct.pack( ">IIII", cls._random_int32(), cls._random_int32(), cls._random_int32(), cls._random_int32(), ), struct.pack(">II", sub_app_id, login_type), cls._pack_lv(str(uin).encode()), struct.pack(">H", 0), # not found in source ) data = qqtea_encrypt(bytes(body), key) return cls._pack_tlv(0x106, data)
def encrypt( cls, data: Union[bytes, Packet], key: Union[bytes, Packet] ) -> Packet: return Packet.build( struct.pack(">BB", 2, 1), key, struct.pack( ">HHH", 305, 1, # oicq.wlogin_sdk.tools.EcdhCrypt.sKeyVersion len(cls.client_public_key), ), cls.client_public_key, qqtea_encrypt(bytes(data), cls.share_key), )
def t400( cls, g: bytes, uin: int, guid: bytes, dpwd: bytes, app_id: int, sub_app_id: int, rand_seed: bytes, _version: int = 1, ) -> "Packet[()]": data = Packet.build( struct.pack(">HQ", _version, uin), guid, dpwd, struct.pack(">III", app_id, sub_app_id, int(time.time())), rand_seed, ) return cls._pack_tlv(0x400, qqtea_encrypt(bytes(data), g))
async def get_sso_list() -> SsoServerResponse: """Do sso server list request and return the response. Note: Source: com.tencent.mobileqq.msf.core.a.f.run Returns: SsoServerResponse: Sso server list response Raises: SsoServerException: Get sso server list failed. """ device = get_device() protocol = get_protocol() key = bytes([ 0xF0, 0x44, 0x1F, 0x5F, 0xF4, 0x2D, 0xA5, 0x8F, 0xDC, 0xF7, 0x94, 0x9A, 0xBA, 0x62, 0xD4, 0x11, ]) payload = SsoServerRequest.to_bytes( 0, SsoServerRequest(app_id=protocol.app_id, imei=device.imei)) req_packet = RequestPacketVersion3( servant_name="HttpServerListReq", func_name="HttpServerListReq", data=types.MAP( {types.STRING("HttpServerListReq"): types.BYTES(payload)}), ).encode(with_length=True) buffer: bytes = qqtea_encrypt(req_packet, key) async with connect("configsvr.msf.3g.qq.com", 443, ssl=True) as conn: query = (b"POST /configsvr/serverlist.jsp HTTP/1.1\r\n" b"Host: configsvr.msf.3g.qq.com\r\n" b"User-Agent: QQ/8.4.1.2703 CFNetwork/1126\r\n" b"Net-Type: Wifi\r\n" b"Accept: */*\r\n" b"Connection: close\r\n" b"Content-Type: application/octet-stream\r\n" b"Content-Length: " + str(len(buffer)).encode() + b"\r\n" b"\r\n" + buffer) conn.write(query) conn.write_eof() resp_bytes = await conn.read_all() response = http.client.HTTPResponse( _FakeSocket(resp_bytes) # type: ignore ) response.begin() if response.status != 200: raise SsoServerException( f"Get sso server list failed with response code {response.status}") data: bytes = qqtea_decrypt(response.read(), key) resp_packet = RequestPacketVersion3.decode(data) server_info = SsoServerResponse.decode( resp_packet.data["HttpServerListRes"][1:-1] # type: ignore ) return server_info
def func(key, text): qqtea_encrypt(text, key)