import base64 from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes def decrypt(base64_input: str, secret: bytes) -> str | None: try: combined = base64.b64decode(base64_input) # IV length is 12 bytes in the Java implementation iv_length = 12 if len(combined) <= iv_length + 16: return None iv = combined[:iv_length] # Java AES/GCM appends a 16-byte authentication tag at the end of cipherBytes # cryptography library expects it to be passed into the modes.GCM(iv, tag) cipher_bytes_with_tag = combined[iv_length:] actual_ciphertext = cipher_bytes_with_tag[:-16] tag = cipher_bytes_with_tag[-16:] cipher = Cipher(algorithms.AES(secret), modes.GCM(iv, tag)) decryptor = cipher.decryptor() plain_bytes = decryptor.update(actual_ciphertext) + decryptor.finalize() return plain_bytes.decode('utf-8') except Exception: return None def get_string_value(encrypted_id: str, secret: str, secret_key_internal: str) -> str | None: if not secret or not secret_key_internal: return None try: # Replicate Java's logic: (s + secretKeyInternal).substring(0, Math.min(..., 16)) combined_str = secret + secret_key_internal combined_secret = combined_str[:16].encode('utf-8') return decrypt(encrypted_id, combined_secret) except Exception: return None