mirror of
https://github.com/Remik1r3n/maimaiDX-Api.git
synced 2025-05-20 04:17:28 +08:00
67 lines
2.1 KiB
Python
67 lines
2.1 KiB
Python
# 舞萌DX Auth-Lite 服务器模拟实现
|
||
# 仅实现了 /net/initialize 接口,用来处理 PowerOn
|
||
|
||
from fastapi import (
|
||
FastAPI,
|
||
Request
|
||
)
|
||
from fastapi.responses import (
|
||
HTMLResponse
|
||
)
|
||
import uvicorn
|
||
import httpx
|
||
from loguru import logger
|
||
from Crypto.Cipher import AES
|
||
from Crypto.Util.Padding import pad, unpad
|
||
|
||
# 从 HDD 提取
|
||
LITE_AUTH_KEY = bytes([47, 63, 106, 111, 43, 34, 76, 38, 92, 67, 114, 57, 40, 61, 107, 71])
|
||
LITE_AUTH_IV = bytes.fromhex('00000000000000000000000000000000')
|
||
|
||
def auth_lite_encrypt(plaintext: str) -> bytes:
|
||
# 构造数据:16字节头 + 16字节0前缀 + 明文
|
||
header = bytes(16)
|
||
content = bytes(16) + plaintext.encode('utf-8')
|
||
data = header + content
|
||
# 填充并加密
|
||
padded_data = pad(data, AES.block_size)
|
||
cipher = AES.new(LITE_AUTH_KEY, AES.MODE_CBC, LITE_AUTH_IV)
|
||
return cipher.encrypt(padded_data)
|
||
|
||
def auth_lite_decrypt(ciphertext: bytes) -> str:
|
||
# 解密并去除填充
|
||
cipher = AES.new(LITE_AUTH_KEY, AES.MODE_CBC, LITE_AUTH_IV)
|
||
decrypted_data = unpad(cipher.decrypt(ciphertext), AES.block_size)
|
||
# 提取内容并解码
|
||
content = decrypted_data[16:] # 去除头部的16字节
|
||
return content.decode('utf-8').strip()
|
||
|
||
def apiOfficialServer(encryptedString: str):
|
||
url = "http://at.sys-allnet.cn/net/initialize"
|
||
headers = {
|
||
"Content-Type": "application/x-www-form-urlencoded",
|
||
"User-Agent": "SDGB;Windows/Lite"
|
||
}
|
||
data = encryptedString
|
||
response = httpx.post(url, headers=headers, data=data)
|
||
return response.content
|
||
|
||
app = FastAPI()
|
||
|
||
USE_OFFICIAL_SERVER = 1
|
||
|
||
@app.post('/net/initialize')
|
||
async def get_data_dummy_api(request: Request):
|
||
gotRequest = (await request.body())
|
||
if USE_OFFICIAL_SERVER == 1:
|
||
decrypted = auth_lite_decrypt(gotRequest)
|
||
officialResponse = apiOfficialServer(auth_lite_encrypt(decrypted))
|
||
logger.info(auth_lite_decrypt(officialResponse))
|
||
return HTMLResponse(officialResponse)
|
||
else:
|
||
# todo
|
||
pass
|
||
|
||
if __name__ == '__main__':
|
||
uvicorn.run(app, host="0.0.0.0", port=80)
|