40 lines
1.3 KiB
Python
40 lines
1.3 KiB
Python
import base64
|
|
import hashlib
|
|
import os
|
|
from pathlib import Path
|
|
|
|
from cryptography.fernet import Fernet, InvalidToken
|
|
|
|
from app.core.security import ADMIN_TOKEN
|
|
from app.services.signing_service import MANIFEST_PRIVATE_KEY_PATH
|
|
|
|
|
|
def license_key_encryption_material() -> bytes:
|
|
# 数据库只存 License Key 的密文和 hash。
|
|
# hash 用于客户端提交 License 时快速匹配;密文用于后台列表需要再次展示原始 Key 的场景。
|
|
configured_secret = os.getenv("LICENSE_KEY_ENCRYPTION_SECRET", "").strip()
|
|
if configured_secret:
|
|
return configured_secret.encode("utf-8")
|
|
key_path = Path(MANIFEST_PRIVATE_KEY_PATH)
|
|
if key_path.exists():
|
|
return key_path.read_bytes()
|
|
return ADMIN_TOKEN.encode("utf-8")
|
|
|
|
|
|
def license_key_cipher() -> Fernet:
|
|
key = base64.urlsafe_b64encode(hashlib.sha256(license_key_encryption_material()).digest())
|
|
return Fernet(key)
|
|
|
|
|
|
def encrypt_license_key(license_key: str) -> str:
|
|
return license_key_cipher().encrypt(license_key.encode("utf-8")).decode("ascii")
|
|
|
|
|
|
def decrypt_license_key(cipher_text: str) -> str:
|
|
if not cipher_text:
|
|
return ""
|
|
try:
|
|
return license_key_cipher().decrypt(cipher_text.encode("ascii")).decode("utf-8")
|
|
except (InvalidToken, UnicodeDecodeError, ValueError):
|
|
return ""
|