Files
crawler-plugin/brand_spider/web_dec.py
铭坤 8a64a6cd9b new file: ali_oss.py
new file:   app.py
	new file:   app/ali_oss.py
	new file:   app/app.py
	new file:   app/app_common.py
	new file:   app/config.py
	new file:   app/coze.py
	new file:   app/generate_api.py
	new file:   app/html_crypto.py
	new file:   app/main.py
	new file:   app/web_source/admin.html
	new file:   app/web_source/brand.html
	new file:   app/web_source/home.html
	new file:   app/web_source/index.html
	new file:   app/web_source/login.html
	new file:   app_common.py
	new file:   blueprints/__init__.py
	new file:   blueprints/__pycache__/__init__.cpython-311.pyc
	new file:   blueprints/__pycache__/__init__.cpython-39.pyc
	new file:   blueprints/__pycache__/admin.cpython-311.pyc
	new file:   blueprints/__pycache__/admin.cpython-39.pyc
	new file:   blueprints/__pycache__/auth.cpython-311.pyc
	new file:   blueprints/__pycache__/auth.cpython-39.pyc
	new file:   blueprints/__pycache__/brand.cpython-311.pyc
	new file:   blueprints/__pycache__/brand.cpython-39.pyc
	new file:   blueprints/__pycache__/image.cpython-311.pyc
	new file:   blueprints/__pycache__/image.cpython-39.pyc
	new file:   blueprints/__pycache__/main.cpython-311.pyc
	new file:   blueprints/__pycache__/main.cpython-39.pyc
	new file:   blueprints/admin.py
	new file:   blueprints/auth.py
	new file:   blueprints/brand.py
	new file:   blueprints/image.py
	new file:   blueprints/main.py
	new file:   brand_spider/__pycache__/main.cpython-39.pyc
	new file:   brand_spider/__pycache__/web_dec.cpython-39.pyc
	new file:   brand_spider/main.py
	new file:   brand_spider/web_dec.py
	new file:   config.py
	new file:   coze.py
	new file:   generate_api.py
	new file:   html_crypto.py
	new file:   main.py
	new file:   static/bg.jpg
	new file:   "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:   "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:   tool/.device_id
	new file:   tool/__pycache__/devices.cpython-311.pyc
	new file:   tool/__pycache__/devices.cpython-39.pyc
	new file:   tool/devices.py
2026-03-20 11:23:57 +08:00

127 lines
4.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
通过 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 对应原 keyciphertext 对应原 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)