# -*- coding: utf-8 -*- """Fernet 加密 / 解密的薄封装。 不暴露 Fernet 对象;调用方只看 encrypt/decrypt 字符串。 """ from __future__ import annotations from cryptography.fernet import Fernet, InvalidToken from service.master_key import load_master_key from service.secret_store import mask_secret class CredentialDecryptError(Exception): """Decryption failed (bad key or corrupted ciphertext).""" code = "ERR_CREDENTIAL_DECRYPT_FAILED" def encrypt_secret(plaintext: str) -> str: """Encrypt using current master key; returns url-safe token string.""" key = load_master_key() f = Fernet(key) tok = f.encrypt(plaintext.encode("utf-8")) return tok.decode("ascii") def decrypt_secret(ciphertext: str) -> str: """Decrypt Fernet token string to plaintext.""" key = load_master_key() f = Fernet(key) try: raw = f.decrypt(ciphertext.encode("ascii")) return raw.decode("utf-8") except InvalidToken as e: raise CredentialDecryptError("Fernet decrypt failed") from e