@@ -45,7 +45,9 @@ class EncryptionService:
4545 False
4646 """
4747
48- def __init__ (self , encryption_secret : Union [SecretStr , str ], time_cost : Optional [int ] = None , memory_cost : Optional [int ] = None , parallelism : Optional [int ] = None , hash_len : int = 32 , salt_len : int = 16 ):
48+ def __init__ (
49+ self , encryption_secret : Union [SecretStr , str ], time_cost : Optional [int ] = None , memory_cost : Optional [int ] = None , parallelism : Optional [int ] = None , hash_len : int = 32 , salt_len : int = 16
50+ ):
4951 """Initialize the encryption handler.
5052
5153 Args:
@@ -151,9 +153,27 @@ def is_encrypted(self, text: str) -> bool:
151153
152154 Returns:
153155 True if the string appears to be encrypted
156+
157+ Note:
158+ Supports both legacy PBKDF2 (base64-wrapped Fernet) and new Argon2id
159+ (JSON bundle) formats. Checks JSON format first, then falls back to
160+ base64 check for legacy format.
154161 """
162+ if not text :
163+ return False
164+
165+ # Check for new Argon2id JSON bundle format
166+ if text .startswith ("{" ):
167+ try :
168+ obj = json .loads (text )
169+ if isinstance (obj , dict ) and obj .get ("kdf" ) == "argon2id" :
170+ return True
171+ except (json .JSONDecodeError , ValueError , KeyError ):
172+ # Not valid JSON or missing expected structure - continue to legacy check
173+ pass
174+
175+ # Check for legacy PBKDF2 base64-wrapped Fernet format
155176 try :
156- # Try to decode as base64 and check if it looks like encrypted data
157177 decoded = base64 .urlsafe_b64decode (text .encode ())
158178 # Encrypted data should be at least 32 bytes (Fernet minimum)
159179 return len (decoded ) >= 32
0 commit comments