From f655a736b36aa27284e4fc0cafb20833680d78ea Mon Sep 17 00:00:00 2001 From: Naiel <109038805+naielv@users.noreply.github.com> Date: Tue, 3 Mar 2026 10:59:02 +0100 Subject: [PATCH] fix --- python_sdk/telesec_couchdb.py | 58 ++++++++++++----------------------- python_sdk/windows_agent.py | 58 ++++++++++++----------------------- 2 files changed, 38 insertions(+), 78 deletions(-) diff --git a/python_sdk/telesec_couchdb.py b/python_sdk/telesec_couchdb.py index 4199638..2228d85 100644 --- a/python_sdk/telesec_couchdb.py +++ b/python_sdk/telesec_couchdb.py @@ -76,52 +76,32 @@ def ts_encrypt(input_value: Any, secret: str) -> str: return f"RSA{{{b64}}}" -def ts_decrypt(input_value: Any, secret: str) -> Any: - """ - Compatible with JS TS_decrypt behavior: - - If not string: return as-is. - - If RSA{...}: decrypt AES(CryptoJS passphrase mode), parse JSON when possible. - - If plain string JSON: parse JSON. - - Else: return raw string. - """ +def ts_encrypt(input_value: Any, secret: str) -> str: if not isinstance(input_value, str): - return input_value + payload = json.dumps(input_value, separators=(",", ":"), ensure_ascii=False) + else: + payload = input_value - is_wrapped = input_value.startswith("RSA{") and input_value.endswith("}") - if is_wrapped: - if not secret: - raise TeleSecCryptoError("Secret is required to decrypt RSA payload") - b64 = input_value[4:-1] - try: - raw = base64.b64decode(b64) - except Exception as exc: - raise TeleSecCryptoError("Invalid base64 payload") from exc + payload_bytes = payload.encode("utf-8") + salt = os.urandom(8) - if len(raw) < 16 or not raw.startswith(b"Salted__"): - raise TeleSecCryptoError("Unsupported encrypted payload format") + # OpenSSL EVP_BytesToKey (MD5) + dx = b"" + salted = b"" + while len(salted) < 48: # 32 key + 16 iv + dx = hashlib.md5(dx + secret.encode() + salt).digest() + salted += dx - salt = raw[8:16] - ciphertext = raw[16:] - key, iv = _evp_bytes_to_key(secret.encode("utf-8"), salt, 32, 16) - cipher = AES.new(key, AES.MODE_CBC, iv=iv) - decrypted = cipher.decrypt(ciphertext) - decrypted = _pkcs7_unpad(decrypted, 16) + key = salted[:32] + iv = salted[32:48] - try: - text = decrypted.decode("utf-8") - except UnicodeDecodeError: - text = decrypted.decode("latin-1") + cipher = AES.new(key, AES.MODE_CBC, iv) + encrypted = cipher.encrypt(_pkcs7_pad(payload_bytes, 16)) - try: - return json.loads(text) - except Exception: - return text - - try: - return json.loads(input_value) - except Exception: - return input_value + openssl_blob = b"Salted__" + salt + encrypted + b64 = base64.b64encode(openssl_blob).decode("utf-8") + return f"RSA{{{b64}}}" @dataclass class TeleSecDoc: diff --git a/python_sdk/windows_agent.py b/python_sdk/windows_agent.py index 11bec13..bdd23d3 100644 --- a/python_sdk/windows_agent.py +++ b/python_sdk/windows_agent.py @@ -84,52 +84,32 @@ def ts_encrypt(input_value: Any, secret: str) -> str: return f"RSA{{{b64}}}" -def ts_decrypt(input_value: Any, secret: str) -> Any: - """ - Compatible with JS TS_decrypt behavior: - - If not string: return as-is. - - If RSA{...}: decrypt AES(CryptoJS passphrase mode), parse JSON when possible. - - If plain string JSON: parse JSON. - - Else: return raw string. - """ +def ts_encrypt(input_value: Any, secret: str) -> str: if not isinstance(input_value, str): - return input_value + payload = json.dumps(input_value, separators=(",", ":"), ensure_ascii=False) + else: + payload = input_value - is_wrapped = input_value.startswith("RSA{") and input_value.endswith("}") - if is_wrapped: - if not secret: - raise TeleSecCryptoError("Secret is required to decrypt RSA payload") - b64 = input_value[4:-1] - try: - raw = base64.b64decode(b64) - except Exception as exc: - raise TeleSecCryptoError("Invalid base64 payload") from exc + payload_bytes = payload.encode("utf-8") + salt = os.urandom(8) - if len(raw) < 16 or not raw.startswith(b"Salted__"): - raise TeleSecCryptoError("Unsupported encrypted payload format") + # OpenSSL EVP_BytesToKey (MD5) + dx = b"" + salted = b"" + while len(salted) < 48: # 32 key + 16 iv + dx = hashlib.md5(dx + secret.encode() + salt).digest() + salted += dx - salt = raw[8:16] - ciphertext = raw[16:] - key, iv = _evp_bytes_to_key(secret.encode("utf-8"), salt, 32, 16) - cipher = AES.new(key, AES.MODE_CBC, iv=iv) - decrypted = cipher.decrypt(ciphertext) - decrypted = _pkcs7_unpad(decrypted, 16) + key = salted[:32] + iv = salted[32:48] - try: - text = decrypted.decode("utf-8") - except UnicodeDecodeError: - text = decrypted.decode("latin-1") + cipher = AES.new(key, AES.MODE_CBC, iv) + encrypted = cipher.encrypt(_pkcs7_pad(payload_bytes, 16)) - try: - return json.loads(text) - except Exception: - return text - - try: - return json.loads(input_value) - except Exception: - return input_value + openssl_blob = b"Salted__" + salt + encrypted + b64 = base64.b64encode(openssl_blob).decode("utf-8") + return f"RSA{{{b64}}}" @dataclass class TeleSecDoc: