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 hashlib import md5
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
from app.utils.common import decrypt
class CookieCloudHelper:
@ -22,11 +26,25 @@ class CookieCloudHelper:
if not self._server or not self._key or not self._password:
return None, "CookieCloud参数不正确"
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:
result = ret.json()
if not result:
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"):
contents = result.get("cookie_data")
else:
@ -66,3 +84,11 @@ class CookieCloudHelper:
return None, f"同步CookieCloud失败错误码{ret.status_code}"
else:
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 base64
from typing import Any
from Crypto import Random
from Crypto.Cipher import AES
from hashlib import md5
def retry(ExceptionToCheck: Any,
@ -32,3 +37,48 @@ def retry(ExceptionToCheck: Any,
return f_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]))]