forked from HomeAssistant/midea-meiju-codec
60 lines
56 KiB
Python
60 lines
56 KiB
Python
![]() |
from Crypto.Cipher import AES
|
||
|
from Crypto.Util.Padding import unpad
|
||
|
|
||
|
from custom_components.midea_auto_cloud.core.security import CloudSecurity
|
||
|
|
||
|
cloud_data = {
|
||
|
"class_name": "MeijuCloud",
|
||
|
"app_id": "900",
|
||
|
"app_key": "46579c15",
|
||
|
"login_key": "ad0ee21d48a64bf49f4fb583ab76e799",
|
||
|
"iot_key": bytes.fromhex(
|
||
|
format(9795516279659324117647275084689641883661667, "x"),
|
||
|
).decode(),
|
||
|
"hmac_key": bytes.fromhex(
|
||
|
format(117390035944627627450677220413733956185864939010425, "x"),
|
||
|
).decode(),
|
||
|
"api_url": "https://mp-prod.smartmidea.net/mas/v5/app/proxy?alias=",
|
||
|
}
|
||
|
|
||
|
cloud_security = CloudSecurity(
|
||
|
login_key=cloud_data["login_key"],
|
||
|
iot_key=cloud_data["iot_key"],
|
||
|
hmac_key=cloud_data["hmac_key"],
|
||
|
),
|
||
|
|
||
|
|
||
|
def aes_decrypt(
|
||
|
data: str | bytes,
|
||
|
key: bytes | None = None,
|
||
|
iv: bytes | None = None,
|
||
|
) -> str:
|
||
|
"""Decrypt AES."""
|
||
|
if len(data) == 0:
|
||
|
return ""
|
||
|
if key is not None:
|
||
|
aes_key = key
|
||
|
aes_iv = iv
|
||
|
if aes_key is None:
|
||
|
raise ValueError("Encrypt need a key")
|
||
|
if isinstance(data, str):
|
||
|
data = bytes.fromhex(data)
|
||
|
if aes_iv is None or aes_iv == b"0": # ECB
|
||
|
return unpad(
|
||
|
AES.new(aes_key, AES.MODE_ECB).decrypt(data),
|
||
|
len(aes_key),
|
||
|
).decode()
|
||
|
return unpad(
|
||
|
AES.new(aes_key, AES.MODE_CBC, iv=aes_iv).decrypt(data),
|
||
|
len(aes_key),
|
||
|
).decode()
|
||
|
|
||
|
lua = "16c66f1d580f6cb5032b87e8aeff8c2cc66c429095b4fdb1196459e890b848740e1fcc0cad9d0a4e86df895af7173436b04220470e450585842601f17d098ad4275eee2e0dd99264ecbb1807d52a5b3247413871d6d97308b945207e8a1913f6e23b202c49dd6f43c0db6bf21dc2306751ac3f2627b3d375f9a75ca746196dc805bf48ebc93d0303261e1be83abbab69a4e5cbc322bbc2b7a0eded83cef88d1bdce36ded1b092cb9e928543c34c1ab7cf104bd9490b9bd96e0d3b8c91081b11bde8799c8f64c70e8ee5447ad2b2d084689154e469e73225fedb38ff0b244e635da52df5572b04678ada9b1f24b3dac2a745f5683eb9da4866bb9f3a09ad5e04e7cc1583ea5cb0e6a42feb29f5f6f30af905ccabfc122cc7f1197fbbeb527a7d48a2bb3655843ca0494222974a68bd47c181341909ec7db9a63ed8cb4f5b8d291799c3df8122d7adca04239851c744b36b9940988b26462086b26c4d1fe4721c291524ad436b7f10e61f538ff6cc763a7bcb75f80308ac8257450781851cf4e7ae7d7541cc765b57bcf3be7ae7ecee4fc088f64bb8047283fbf263debc75f00f3fc590d5a685791d1ea8cdbb1635bf48154097360b043fc81d40e054fb21aba3a0266e5980773f10d92053150e114a7a10441992dad71800ef63443d5a0fa63240606c31b89fa951e72cfbb8f5145cafd9d6b00b39dc08f8cb75e6c84d5e0b6bc3762c00395e3ae8ea39a96efd6aa1031122c3927189db5fe1c6995efb0a5c90eb5e1e79c5fb9a0bddfb7c323ac335bff1589db6d91a5666c5cbd20d728c2cbe4fe4d202e3ec6e762b15b5e37ca89c7d4d85b44ad9159df74c3f89f7c2263eb355f7ba225f42c0f762ec23078a5a42e02bcbe9031c95d2edbd7ab98679778e3c90a04f26e5a1f18d397e9b91bee8947f0b6f844b9bf18706d9233bb7f6ad76713091087bd5a636cad22c6201102240b545c63e36c3f6c0cd266e198761b34f1e6b6f844b9bf18706d9233bb7f6ad7671332bbcb1b803b0b1cb5df72927edae9b883e3aec437db79370351319367a7073e697f5770379321069e6708640ca124238c7f454a178e544afc957e68ba2987728885a9e56339bb2a954daa5630c373fb6fe03d089e9cfcf16a89512abb4e3212db328d2c31b6d9af1a9dcd3d3fd5405fba1d0b99d5be240df48fc6fd56a475386870f765085c38bef94342364a434a90a640032c9f8b9e31e0c87ff195da30e0f35306e1d6977e73041b2e154d7851a6682a6d725d84bfb48a14a328dbe654377db24ae233ac3110913adb345b1bcd19ea4a12970b03011e81270bd1c6196d574e31e557621160c9992752cfd4221e971ee48d5c0cc0ea472753a51f2fd5131a0e0ee0656d081e1bd71446e3bbc58daf91ec7efb30013f1cce81a29c2a9130b2f3386f638bee0a262353aeb5a507856b083b63b0c79329ea313714708bfcdcfd80fcfd47014b3a26b4fbfd348c616294a1f159c0d60facaf782bceb1f137f136f3386f638bee0a262353aeb5a507856ba76940f263e13b6a9864896d6ec0cda714e08e246c8d5ffb67c5247dc119bea0f7172c69508a73947db6f83c03d7f1b3be83e44009213e84e17fcef1b3fe1ad1388a8ca868e29a5f5b59de4a7d3ef73f5dcf7cbb80261632b3c92fcd21aeaf33b817b250c30dd24a132b846a2304fae6b0752ee4558b3d93086f3b9ff964cbb47745cc890864ac7c76d6d36eab12368dd8a4bf5bedc8a0b8a3550aac309841f331a5311bff8be4ddd5febdf3d0f54bf36585776246a4c6a8ee7c05d7078e3f600da2ac3f19252c895e4da6e685b1d9ee3e402668cf085441e71447678b48f6d3a3b7abe53237f28e4a270725a89dafe3b060e121eef20e79404d2026ce0e3a1cf875acb7dd0ac932f2cfa2cf0ee7bb564e9d6220f84560fe3b2af93f87217bce0e415f1b3e4398c06eaf63903cd0de7fe54ca5443a8846f3748083963ade249e43e33315b923fb4743636f0c8acb1a9cbc934573b6d92752959d5e459bb823f6425849a6219ee273166351e602377597e54f1f38295533aac11275297fd95deec293c529c9cda2072073a1cd7d501123b91233636b82bc110320855a320b7225aa7174a7b10a36f5c9bb7b738a8892adb2036fcbac9a011e831594adfd7cd230136cba8c64a61cba4c7f28dc838774335e619f41c6a560444db967096c0777560e6e6e833c4bd2d6eb948e8a478be899b37e5ee3c6604f68f788674600e670211b71e3b32561c55e486fcbdf7861ff8db048317e8cff38ee87593f97575104523cc1fa4eec87c9c170eae526ac6275af71c4bd574cab80c98f5bd43cde93b7a13f0f68515a9b92e7b4e9b9e68d02286035baf9df34cd54de2ea79b722d0c53813cc1fa4eec87c9c170eae526ac6275af2339a19147093e2a2bea5dc498065c783f0f68515a9b92e7b4e9b9e68d02286045b11caa276b40447dae81f2bedf7d11cede6c87bcbe69da6af599311397f0e7e3c98728f99fe2a226ed327a608c44b04d0f0d587030fc344f159be13ec6171a368e3bc7bb961cac593ef85ff2222e8efc59eb938928dcc8fc40bfc74ae5216fb10a67586f32761b59cb9cd4b906bc5bcede6c87bcbe69da6af599311397f0e7da2c6d9cc87820e49f70faa8dc7da900c13deccb6eb1de47819bbe31cba7ef44ecb78ed60d127561cf290fed729326ebb100b16ecd92813395ccea98de031627f45bb79d481a1ae9549e049551c7259bde4a27cd4a30e88c6bf8c74af5bac4fa8987584d8bdfcd09dacbc5f10c24959054027eb1b08f44438a25d8a1d4b5ec0623d0a516551d8370233ad819738ea4c7cbad6e91756a73b7c854e7669dbde846b2c7dd82499cc05eae7f9de6
|
||
|
stream = (
|
||
|
'local bit = require "bit"\n'
|
||
|
+ aes_decrypt(lua, format(10864842703515613082, "x").encode("ascii"), None)
|
||
|
)
|
||
|
stream = stream.replace("\r\n", "\n")
|
||
|
fnm = f"T_0000_CC_6.lua"
|
||
|
with open(fnm, "w") as fp:
|
||
|
fp.write(stream)
|