跳转至

utils.qimei

QIMEI 获取

QimeiResult

Bases: TypedDict

获取 QIMEI 结果

rsa_encrypt

rsa_encrypt(content: bytes) -> bytes

RSA 加密

Source code in qqmusic_api/utils/qimei.py
def rsa_encrypt(content: bytes) -> bytes:
    """RSA 加密"""
    key = cast(RSAPublicKey, serialization.load_pem_public_key(PUBLIC_KEY.encode()))
    return key.encrypt(content, padding.PKCS1v15())

aes_encrypt

aes_encrypt(key: bytes, content: bytes) -> bytes

AES-CBC 加密数据

Source code in qqmusic_api/utils/qimei.py
def aes_encrypt(key: bytes, content: bytes) -> bytes:
    """AES-CBC 加密数据"""
    cipher = Cipher(algorithms.AES(key), modes.CBC(key))
    padding_size = 16 - len(content) % 16
    encryptor = cipher.encryptor()
    return encryptor.update(content + (padding_size * chr(padding_size)).encode()) + encryptor.finalize()

random_beacon_id

random_beacon_id() -> str

随机 BeaconID

Source code in qqmusic_api/utils/qimei.py
def random_beacon_id() -> str:
    """随机 BeaconID"""
    beacon_id = ""
    time_month = datetime.now().strftime("%Y-%m-") + "01"
    rand1 = random.randint(100000, 999999)
    rand2 = random.randint(100000000, 999999999)

    for i in range(1, 41):
        if i in [1, 2, 13, 14, 17, 18, 21, 22, 25, 26, 29, 30, 33, 34, 37, 38]:
            beacon_id += f"k{i}:{time_month}{rand1}.{rand2}"
        elif i == 3:
            beacon_id += "k3:0000000000000000"
        elif i == 4:
            beacon_id += f"k4:{''.join(random.choices('123456789abcdef', k=16))}"
        else:
            beacon_id += f"k{i}:{random.randint(0, 9999)}"
        beacon_id += ";"
    return beacon_id

random_payload_by_device

random_payload_by_device(device: Device, version: str) -> dict

随机 payload

Source code in qqmusic_api/utils/qimei.py
def random_payload_by_device(device: Device, version: str) -> dict:
    """随机 payload"""
    fixed_rand = random.randint(0, 14400)
    reserved = {
        "harmony": "0",
        "clone": "0",
        "containe": "",
        "oz": "UhYmelwouA+V2nPWbOvLTgN2/m8jwGB+yUB5v9tysQg=",
        "oo": "Xecjt+9S1+f8Pz2VLSxgpw==",
        "kelong": "0",
        "uptimes": (datetime.now() - timedelta(seconds=fixed_rand)).strftime("%Y-%m-%d %H:%M:%S"),
        "multiUser": "0",
        "bod": device.brand,
        "dv": device.device,
        "firstLevel": "",
        "manufact": device.brand,
        "name": device.model,
        "host": "se.infra",
        "kernel": device.proc_version,
    }
    return {
        "androidId": device.android_id,
        "platformId": 1,
        "appKey": APP_KEY,
        "appVersion": version,
        "beaconIdSrc": random_beacon_id(),
        "brand": device.brand,
        "channelId": "10003505",
        "cid": "",
        "imei": device.imei,
        "imsi": "",
        "mac": "",
        "model": device.model,
        "networkType": "unknown",
        "oaid": "",
        "osVersion": f"Android {device.version.release},level {device.version.sdk}",
        "qimei": "",
        "qimei36": "",
        "sdkVersion": "1.2.13.6",
        "targetSdkVersion": "33",
        "audit": "",
        "userId": "{}",
        "packageId": "com.tencent.qqmusic",
        "deviceType": "Phone",
        "sdkName": "",
        "reserved": json.dumps(reserved, separators=(",", ":"), ensure_ascii=False),
    }

get_qimei

get_qimei(device: Device, version: str) -> QimeiResult

获取 QIMEI

Source code in qqmusic_api/utils/qimei.py
def get_qimei(device: Device, version: str) -> QimeiResult:
    """获取 QIMEI"""
    from .. import logger

    try:
        payload = random_payload_by_device(device, version)
        crypt_key = "".join(random.choices("adbcdef1234567890", k=16))
        nonce = "".join(random.choices("adbcdef1234567890", k=16))
        ts = int(time())
        key = base64.b64encode(rsa_encrypt(crypt_key.encode())).decode()
        params = base64.b64encode(aes_encrypt(crypt_key.encode(), json.dumps(payload).encode())).decode()
        extra = '{"appKey":"' + APP_KEY + '"}'
        sign = calc_md5(key, params, str(ts * 1000), nonce, SECRET, extra)
        res = httpx.post(
            "https://api.tencentmusic.com/tme/trpc/proxy",
            headers={
                "Host": "api.tencentmusic.com",
                "method": "GetQimei",
                "service": "trpc.tme_datasvr.qimeiproxy.QimeiProxy",
                "appid": "qimei_qq_android",
                "sign": calc_md5("qimei_qq_androidpzAuCmaFAaFaHrdakPjLIEqKrGnSOOvH", str(ts)),
                "user-agent": "QQMusic",
                "timestamp": str(ts),
            },
            json={
                "app": 0,
                "os": 1,
                "qimeiParams": {
                    "key": key,
                    "params": params,
                    "time": str(ts),
                    "nonce": nonce,
                    "sign": sign,
                    "extra": extra,
                },
            },
        )
        logger.debug("获取 QIMEI 成功: %s", res.json())
        return json.loads(res.json()["data"])["data"]
    except Exception:
        logger.exception("获取 QIMEI 失败,使用默认 QIMEI")
        return QimeiResult(q16="", q36="6c9d3cd110abca9b16311cee10001e717614")