Anonimizacja z kluczem publicznym i prywatnym¶
Ten przykład dodaje szyfrowanie kluczem publicznym RSA i odtwarzanie kluczem prywatnym do bezstanowej anonimizacji odwracalnej. RSA-3072 OAEP-SHA256 szyfruje nowy klucz AES-256-GCM dla każdego tokenu. Osobny klucz uwierzytelniania wystawcy, wyprowadzony z istniejącego lokalnego zbioru kluczy, uwierzytelnia całą kopertę przed odszyfrowaniem RSA. Implementacja korzysta z mechanizmów RSA i AEAD biblioteki cryptography.
Nie powstaje baza konwersacji ani mapowanie jawnymi wartościami. Weryfikacja tokenu pozostaje związana z zaufanym tenantem, tożsamością, odciskiem aktywnej reguły i terminem ważności. Stabilne identyfikatory w danym zakresie rozpoznają jednakowe wartości oryginalne; zaszyfrowane tokeny nadal są losowane.
1. Wygeneruj klucze raz¶
Po zainstalowaniu FastFence i rozpakowaniu archiwum przykładów do examples/ wykonaj w katalogu instalacji:
uv tool run --python 3.12 [email protected] init --anonymization
uv run --python 3.12 --no-project --with fastfence==1.0.1 python examples/asymmetric_keys.py
Pierwsze polecenie tworzy prywatny zbiór kluczy wystawcy, jeśli go brakuje. Drugie tworzy state/private/anonymization-rsa/public.pem i private.pem z uprawnieniami 0600. Odmawia nadpisania któregokolwiek pliku. Ponowne wykonanie nie jest poleceniem rotacji kluczy.
Kompletny wykonywalny generator kluczy jest osadzony bezpośrednio ze źródła:
"""Generate an RSA-3072 recipient pair without overwriting any existing file."""
import argparse
import os
from pathlib import Path
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
def generate_pair(directory: Path) -> tuple[Path, Path]:
directory.mkdir(parents=True, exist_ok=True, mode=0o700)
public_path = directory / "public.pem"
private_path = directory / "private.pem"
if public_path.exists() or private_path.exists():
raise FileExistsError("Refusing to overwrite an existing RSA key pair")
private = rsa.generate_private_key(public_exponent=65537, key_size=3072)
values = (
(
private_path,
private.private_bytes(
serialization.Encoding.PEM,
serialization.PrivateFormat.PKCS8,
serialization.NoEncryption(),
),
),
(
public_path,
private.public_key().public_bytes(
serialization.Encoding.PEM,
serialization.PublicFormat.SubjectPublicKeyInfo,
),
),
)
created = []
try:
for path, data in values:
descriptor = os.open(
path, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600
)
created.append(path)
with os.fdopen(descriptor, "wb") as stream:
stream.write(data)
stream.flush()
os.fsync(stream.fileno())
except OSError:
for path in created:
path.unlink(missing_ok=True)
raise
return public_path, private_path
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--directory",
type=Path,
default=Path("state/private/anonymization-rsa"),
)
args = parser.parse_args()
try:
public, private = generate_pair(args.directory)
except OSError as error:
raise SystemExit(f"Key generation failed: {error}") from None
print(f"Public encryption key: {public}")
print(f"Private recovery key: {private}")
print(
"Keep private.pem and the issuer keyring private; neither belongs in Git."
)
if __name__ == "__main__":
main()
Pobierz asymmetric_keys.py · Zobacz źródło
2. Skonfiguruj bramkę¶
Ustaw obie ścieżki w powłoce uruchamiającej FastFence lub dodaj te ustawienia do własnego .env:
export FASTFENCE_ANONYMIZATION_PUBLIC_KEY_FILE=state/private/anonymization-rsa/public.pem
export FASTFENCE_ANONYMIZATION_PRIVATE_KEY_FILE=state/private/anonymization-rsa/private.pem
uv tool run --python 3.12 [email protected] doctor
uv tool run --python 3.12 [email protected] serve
Względne ścieżki RSA są rozwiązywane względem FASTFENCE_ROOT (domyślnie katalog roboczy). Oba pliki PEM muszą opisywać tę samą parę RSA-3072 z wykładnikiem publicznym 65537. Istniejący zbiór kluczy wystawcy state/anonymization-keys.json nadal jest wymagany: samo szyfrowanie kluczem publicznym nie uwierzytelnia wystawcy tokenu i nie tworzy stabilnych aliasów opartych na kluczu.
Klucze są ładowane raz podczas startu. Po zmianie ustawień kluczy uruchom bramkę ponownie. Pełna bramka wymaga klucza prywatnego nawet przy wyłączonym przywracaniu odpowiedzi, ponieważ wewnętrznie odszyfrowuje otrzymane tokeny do kontroli zgodnie z aktualnymi zasadami. Nie zaimplementowano bramki przekazującej tylko z kluczem publicznym ani trybu odzyskiwania z kluczem wyłącznie po stronie klienta.
Przechowuj private.pem i zbiór kluczy wystawcy prywatnie, poza Git. Publiczny PEM można udostępniać jako publiczny klucz szyfrowania; samo jego posiadanie nie pozwala stworzyć podrobionego tokenu akceptowanego przez FastFence.
3. Włącz regułę odwracalną¶
W Policies → Add anonymization rule ustaw dopasowanie literalne, np. Anna Kowalska, etykietę zamiennika PERSON i właściwy zakres wejścia/wyjścia oraz modelu/narzędzia. Zezwól na jawne przywracanie, jeśli chcesz udostępnić tę opcję. Przejrzyj konfigurację kandydata i przed aktywacją ustaw tryb odzyskiwania Reversible w formularzu ustawień.
Poniżej znajduje się odpowiednia sekcja polityki. Dołącz ją do pełnej polityki zamiast zastępować cały plik:
anonymization:
enabled: true
mode: reversible
rules:
- id: person
operator: literal
value: Anna Kowalska
replacement: PERSON
direction: both
target: all
allow_restore: true
Po skonfigurowaniu pary RSA nowe tokeny odwracalne zaczynają się od [FFR2.. Dotychczasowe symetryczne tokeny [FFR1. pozostają weryfikowalne, dopóki dostępny jest ich klucz wystawcy i pasująca reguła oraz nie upłynęła ważność. Zachowanie nieodwracalnych [FFI1. pozostaje bez zmian.
4. Sprawdź wejście i wyjście¶
Użyj przykładu chronionego żądania lub Test requests, aby wysłać tekst objęty regułą. Przy wyłączonym przywracaniu model otrzymuje token, a odpowiedź zachowuje chronioną postać wartości. Przy restore_originals: true w żądaniu i allow_restore: true w regule bramka może odtworzyć kompletne poprawne tokeny w dostarczanej odpowiedzi.
Model może pominąć lub zmienić tokeny. FastFence nie odtwarza niepełnego szyfrogramu i nie zgaduje brakującej wartości oryginalnej. Po przywróceniu nadal obowiązują kontrole prywatności i blokowania wyjścia; uprawnienie do przywracania ich nie zastępuje.
Czas życia kluczy i wydajność¶
Ta implementacja ładuje jedną parę RSA odbiorcy. Jej wymiana uniemożliwia odczyt wcześniejszych tokenów FFR2, nawet jeśli zbiór kluczy wystawcy zachowuje stare klucze wystawcy. Zachowaj pierwotną parę przez wymagany okres odzyskiwania albo poczekaj na wygaśnięcie tokenów przed zmianą; automatyczna rotacja wielu odbiorców nie jest zaimplementowana. Usunięcie klucza wystawcy unieważnia także tokeny nim uwierzytelnione.
Koperty RSA dodają bajty i operacje asymetryczne względem tokenów symetrycznych. Konfiguracja jest odczytywana tylko przy starcie, ale ten tryb nie ma deklarowanej latencji równej lokalnemu dopasowaniu literalnemu. Nadal obowiązują ograniczenia długości tokenu i wartości, rozmiaru żądania oraz liczby zamian; zbyt duże wartości są odrzucane.