39 lines
1.5 KiB
Python
39 lines
1.5 KiB
Python
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
|