Merge pull request #1683 from lingjiameng/main

This commit is contained in:
jxxghp 2024-03-15 07:55:01 +08:00 committed by GitHub
commit ae6440bd0a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 78 additions and 2 deletions

View File

@ -1,7 +1,11 @@
import json
from typing import Tuple, Optional from typing import Tuple, Optional
from hashlib import md5
from app.utils.http import RequestUtils from app.utils.http import RequestUtils
from app.utils.string import StringUtils from app.utils.string import StringUtils
from app.utils.common import decrypt
class CookieCloudHelper: class CookieCloudHelper:
@ -22,11 +26,25 @@ class CookieCloudHelper:
if not self._server or not self._key or not self._password: if not self._server or not self._key or not self._password:
return None, "CookieCloud参数不正确" return None, "CookieCloud参数不正确"
req_url = "%s/get/%s" % (self._server, str(self._key).strip()) req_url = "%s/get/%s" % (self._server, str(self._key).strip())
ret = self._req.post_res(url=req_url, json={"password": str(self._password).strip()}) ret = self._req.get_res(url=req_url)
if ret and ret.status_code == 200: if ret and ret.status_code == 200:
result = ret.json() result = ret.json()
if not result: if not result:
return {}, "未下载到数据" return {}, "未下载到数据"
encrypted = result.get("encrypted")
if not encrypted:
return {}, "未获取到cookie密文"
else:
crypt_key = self.get_crypt_key()
try:
decrypted_data = decrypt(encrypted, crypt_key).decode('utf-8')
result = json.loads(decrypted_data)
except Exception as e:
return {}, "cookie解密失败" + str(e)
if not result:
return {}, "cookie解密为空"
if result.get("cookie_data"): if result.get("cookie_data"):
contents = result.get("cookie_data") contents = result.get("cookie_data")
else: else:
@ -66,3 +84,11 @@ class CookieCloudHelper:
return None, f"同步CookieCloud失败错误码{ret.status_code}" return None, f"同步CookieCloud失败错误码{ret.status_code}"
else: else:
return None, "CookieCloud请求失败请检查服务器地址、用户KEY及加密密码是否正确" return None, "CookieCloud请求失败请检查服务器地址、用户KEY及加密密码是否正确"
def get_crypt_key(self) -> bytes:
"""
使用UUID和密码生成CookieCloud的加解密密钥
"""
md5_generator = md5()
md5_generator.update((str(self._key).strip() + '-' + str(self._password).strip()).encode('utf-8'))
return (md5_generator.hexdigest()[:16]).encode('utf-8')

View File

@ -1,5 +1,10 @@
import time import time
import base64
from typing import Any from typing import Any
from Crypto import Random
from Crypto.Cipher import AES
from hashlib import md5
def retry(ExceptionToCheck: Any, def retry(ExceptionToCheck: Any,
@ -32,3 +37,48 @@ def retry(ExceptionToCheck: Any,
return f_retry return f_retry
return deco_retry return deco_retry
def bytes_to_key(data: bytes, salt: bytes, output=48) -> bytes:
# extended from https://gist.github.com/gsakkis/4546068
assert len(salt) == 8, len(salt)
data += salt
key = md5(data).digest()
final_key = key
while len(final_key) < output:
key = md5(key + data).digest()
final_key += key
return final_key[:output]
def encrypt(message: bytes, passphrase: bytes) -> bytes:
"""
CryptoJS 加密原文
This is a modified copy of https://stackoverflow.com/questions/36762098/how-to-decrypt-password-from-javascript-cryptojs-aes-encryptpassword-passphras
"""
salt = Random.new().read(8)
key_iv = bytes_to_key(passphrase, salt, 32 + 16)
key = key_iv[:32]
iv = key_iv[32:]
aes = AES.new(key, AES.MODE_CBC, iv)
length = 16 - (len(message) % 16)
data = message + (chr(length) * length).encode()
return base64.b64encode(b"Salted__" + salt + aes.encrypt(data))
def decrypt(encrypted: str | bytes, passphrase: bytes) -> bytes:
"""
CryptoJS 解密密文
来源同encrypt
"""
encrypted = base64.b64decode(encrypted)
assert encrypted[0:8] == b"Salted__"
salt = encrypted[8:16]
key_iv = bytes_to_key(passphrase, salt, 32 + 16)
key = key_iv[:32]
iv = key_iv[32:]
aes = AES.new(key, AES.MODE_CBC, iv)
data = aes.decrypt(encrypted[16:])
return data[:-(data[-1] if type(data[-1]) == int else ord(data[-1]))]