new file: app/blueprints/__pycache__/__init__.cpython-311.pyc new file: app/blueprints/__pycache__/__init__.cpython-39.pyc new file: app/blueprints/__pycache__/admin.cpython-311.pyc new file: app/blueprints/__pycache__/admin.cpython-39.pyc new file: app/blueprints/__pycache__/auth.cpython-311.pyc new file: app/blueprints/__pycache__/auth.cpython-39.pyc new file: app/blueprints/__pycache__/brand.cpython-311.pyc new file: app/blueprints/__pycache__/brand.cpython-39.pyc new file: app/blueprints/__pycache__/image.cpython-311.pyc new file: app/blueprints/__pycache__/image.cpython-39.pyc new file: app/blueprints/__pycache__/main.cpython-311.pyc new file: app/blueprints/__pycache__/main.cpython-39.pyc new file: app/blueprints/admin.py new file: app/blueprints/auth.py new file: app/blueprints/brand.py new file: app/blueprints/image.py new file: app/blueprints/main.py new file: app/brand_spider/__pycache__/main.cpython-39.pyc new file: app/brand_spider/__pycache__/web_dec.cpython-39.pyc new file: app/brand_spider/main.py new file: app/brand_spider/web_dec.py new file: app/static/bg.jpg new file: "app/static/\345\223\201\347\211\214\346\226\207\346\241\243\346\240\274\345\274\217_\346\250\241\346\235\277.xlsx" new file: "app/static/\346\250\241\346\235\2772-\344\273\245\346\226\207\344\273\266\345\244\271\346\226\271\345\274\217\344\270\212\344\274\240.zip" new file: app/tool/.device_id new file: app/tool/__pycache__/devices.cpython-311.pyc new file: app/tool/__pycache__/devices.cpython-39.pyc new file: app/tool/devices.py
127 lines
4.8 KiB
Python
127 lines
4.8 KiB
Python
"""
|
||
通过 pywebview 加载本地 HTML,执行 JS 实现解密与 GUID 生成。
|
||
"""
|
||
import json
|
||
import threading
|
||
import traceback
|
||
|
||
import webview
|
||
|
||
# 内嵌 HTML:加载 CryptoJS 并定义 decryptWithHashSearches、guid
|
||
_DECRYPT_HTML = """
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
|
||
</head>
|
||
<body>
|
||
<script>
|
||
function decryptWithHashSearches(ciphertext, hashSearches) {
|
||
try {
|
||
var baseKey = "8?)i_~Nk6qv0IX;2";
|
||
var keyStr = baseKey + (hashSearches || "");
|
||
var key = CryptoJS.enc.Utf8.parse(keyStr);
|
||
|
||
var decrypted = CryptoJS.AES.decrypt(ciphertext, key, {
|
||
mode: CryptoJS.mode.ECB
|
||
});
|
||
|
||
return decrypted.toString(CryptoJS.enc.Utf8);
|
||
} catch (error) {
|
||
console.error('解密失败:', error.message);
|
||
return '';
|
||
}
|
||
}
|
||
|
||
function guid() {
|
||
function _p8(s) {
|
||
var p = (Math.random().toString(16) + "000000000").substr(2, 8);
|
||
return s ? "-" + p.substr(0, 4) + "-" + p.substr(4, 4) : p;
|
||
}
|
||
return _p8() + _p8(true) + _p8(true) + _p8();
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|
||
"""
|
||
|
||
_window = None
|
||
_window_ready = threading.Event()
|
||
_init_lock = threading.Lock()
|
||
|
||
|
||
def _ensure_window():
|
||
"""首次调用时在后台线程启动 pywebview 并等待页面加载完成。"""
|
||
global _window
|
||
with _init_lock:
|
||
if _window is not None:
|
||
return
|
||
_window = webview.create_window(
|
||
"",
|
||
html=_DECRYPT_HTML,
|
||
width=1,
|
||
height=1,
|
||
hidden=True,
|
||
)
|
||
|
||
def run():
|
||
webview.start(debug=False)
|
||
|
||
t = threading.Thread(target=run, daemon=True)
|
||
t.start()
|
||
_window.events.loaded.wait()
|
||
_window_ready.set()
|
||
_window_ready.wait()
|
||
|
||
|
||
def decrypt_via_service(hash_searches, ciphertext):
|
||
"""
|
||
通过 pywebview 执行 JS decryptWithHashSearches 进行 AES-ECB 解密。
|
||
|
||
:param hash_searches: 对应 JS 的 hashSearches(密钥后缀,可为空串)
|
||
:param ciphertext: Base64 密文
|
||
:return: 解密后的 UTF-8 字符串,失败返回空串
|
||
"""
|
||
_ensure_window()
|
||
# 将参数安全注入 JS(避免注入与引号问题)
|
||
ciphertext_js = json.dumps(ciphertext)
|
||
hash_searches_js = json.dumps(hash_searches or "")
|
||
js = f"(function(){{ return decryptWithHashSearches({ciphertext_js}, {hash_searches_js}); }})();"
|
||
try:
|
||
result = _window.evaluate_js(js)
|
||
return result if result is not None else ""
|
||
except Exception as e:
|
||
raise RuntimeError(f"解密失败: {e}") from e
|
||
|
||
|
||
def get_guid():
|
||
"""通过 pywebview 执行 JS guid() 生成 UUID 格式字符串。"""
|
||
_ensure_window()
|
||
try:
|
||
result = _window.evaluate_js("(function(){ return guid(); })();")
|
||
if result is None:
|
||
raise RuntimeError("guid() 返回为空")
|
||
return result
|
||
except Exception as e:
|
||
raise RuntimeError(f"获取 GUID 失败: {e}") from e
|
||
|
||
|
||
# 使用示例
|
||
if __name__ == "__main__":
|
||
# 参数含义:hash_searches 对应原 key,ciphertext 对应原 data
|
||
hash_searches = "a6efb809-b714-7efd-4b64-8c650b9030f0"
|
||
ciphertext = "SEsfpOGa8B+sWk0ncknTNh/HNHbGiEVi/RNKxBvyHmAE5VjHonPi202c6VicC/GKfA8mLsIC5mGEpSaH2DdCaEJKeOTWD9SBHHbgtyS1O60VqjgAaptYe9LivvWKc/BU8sZOqhxPMzGUHDcKUts7d0p+hCc80XCXyM2ZT80smM1twndcDfpGkLDk2kJbzl2bGzIc60sl9MzKWfZA2sE0ztFjQ9wD2uhn5LrwoN8NnpiPLNbviMMGtHh4N6Dc0xtPzkzgfkiuxBfWnN1SeM9XVgujHvAGea/dqUWIJqLo26fZIOEFJ0MYL4c8CGLYIeP/70cT2IqJdf+IPBWsCiP29zSyAiQd3yLNvd8+xBLky7lR4ng3MZizn/vhW/5BSg1FtVglbAmNbKgHOIbtpP197Lv+uahx2IpsSPqpy4j2O2VV25YzBk9JpJ4WGG/SvF3f2ZYKKepEQ+kGmBxAfG/5Z8DTNIwnOpXhyjFpJb+fUdPV6LTCK/yFc8g31bNFAJkLW7y/VjewjFravZ3VfQjNAHCvifnrIxGG22MZ3TLVnlbh6ye6vTnd+v9GzqXu+ISR7vQGL/ZSM/bJIjuVkP2XnNUPf+NFdt75gyDmTylFmmbpg7WHaBjinPcyVjeZ38+quJhT8yEk66BOjBM47mVdfU8JLK3ToghxQ54dKWGUbc9HRzYIAQ0rIBBExcOcPM4J9DpufvajmEygoDaws4CxOQDlFoFLwNBYorJsKzAoDe1Cu8oFtk4x190Vd+leRKq6DQSNJwEmyrVkWyFpiuywSMaixFlSqve0lRs50FclXfV7gkBAAvz/DJp90i9yCJdMaihP5ZCvbhKxFGMowkU+tx5Ptnxd9hq6tUxHmuiwDI1eyY8EyjB+3MbrC3H/GY39Z5Qhkj5tkSBm4oGA/h6YjeunBlfMU/QGP3hyZIYALh/YmBlZxAcglWwcqlISUhcx1L3Dbw6ZQbpAmYHmA421xIlRJkdJuPmGoopcoFEVdIO0Ov3uP2JL5ybvUgCBMnbwcYRK9qRmvn2b8jHKch55YXerHBDCEMHz88rfgNIEL8DIAp+wMuIyJ0VrV0BwAXioLYNvMcggBp06gghq2NykGiXRZ/dz8nffFqPVkDNjzcPSGrml9fpKdO8x/GannMNBsA+oHlO2/d4dyo+Q2dZCarQ5UB/N1p+UsTW90kvITKwCbZfV/YY2NRm7HrXq+wLS1vY4mChY82Ybc3cYQT653Q=="
|
||
|
||
try:
|
||
decrypted_text = decrypt_via_service(hash_searches, ciphertext)
|
||
print("解密结果:", decrypted_text)
|
||
except Exception as e:
|
||
print("错误:", e)
|
||
|
||
try:
|
||
g = get_guid()
|
||
print("GUID:", g)
|
||
except Exception as e:
|
||
print("GUID 错误:", e)
|