# HG changeset patch # User RhodeCode Admin # Date 2024-04-22 09:32:01 # Node ID 7bfb02ec6478ffa5f43452408288ba146ae3870a # Parent f6cf85522be716b8e0136548c3cdf3f095d42197 fix(encryptor): use a failsafe mechanism of detecting old algo for encryption to NOT crash the app when switching to fernet diff --git a/rhodecode/lib/enc_utils.py b/rhodecode/lib/enc_utils.py --- a/rhodecode/lib/enc_utils.py +++ b/rhodecode/lib/enc_utils.py @@ -30,15 +30,15 @@ def encrypt_value(value: bytes, enc_key: def decrypt_value(value: bytes, enc_key: bytes, algo: str = '', strict_mode: bool = False): + enc_key = safe_bytes(enc_key) + value = safe_bytes(value) if not algo: # not explicit algo, just use what's set by config - algo = get_default_algo() + algo = Encryptor.detect_enc_algo(value) or get_default_algo() if algo not in ALLOWED_ALGOS: ValueError(f'Bad encryption algorithm, should be {ALLOWED_ALGOS}, got: {algo}') - enc_key = safe_bytes(enc_key) - value = safe_bytes(value) safe = not strict_mode if algo == 'aes': diff --git a/rhodecode/lib/encrypt2.py b/rhodecode/lib/encrypt2.py --- a/rhodecode/lib/encrypt2.py +++ b/rhodecode/lib/encrypt2.py @@ -23,8 +23,21 @@ class InvalidDecryptedValue(str): class Encryptor(object): key_format = b'enc2$salt:{1}$data:{2}' + pref_len = 5 # salt:, data: + @classmethod + def detect_enc_algo(cls, enc_data: bytes): + parts = enc_data.split(b'$', 3) + if len(parts) != 3: + raise ValueError(f'Encrypted Data has invalid format, expected {cls.key_format}, got {parts}') + + if b'enc$aes_hmac$' in enc_data: + return 'aes' + elif b'enc2$salt' in enc_data: + return 'fernet' + return None + def __init__(self, enc_key: bytes): self.enc_key = enc_key