Zbiory kluczy

Tink używa zestawów kluczy do rotacji kluczy. Formalnie zestaw kluczy to niepusty1, w którym jeden klucz jest oznaczony jako podstawowy (używany na przykład do podpisywania i szyfrowania nowych tekstów jawnych). Dodatkowo klucze w kobiecie mają unikalny identyfikator2 oraz stan klucza, który umożliwia wyłączenie kluczy bez ich usuwania z kobieca.

Klucze są głównym sposobem, w jaki użytkownicy mogą uzyskiwać dostęp do kluczy (za pomocą klasy KeysetHandle). Dzięki temu każdy użytkownik ma kod do obsługi wielu kluczy jednocześnie. Większość użytkowników kryptografii musi obsługiwać wiele kluczy: musi istnieć możliwość zmiany kluczy (stare klucze mogą zostać ujawnione) i prawie nigdy nie ma możliwości „przełączenia się na następny klucz”, która mogłaby być stosowana na wszystkich maszynach, na których działa kod, i na wszystkich tekstach zaszyfrowanych w całości i w błyskawicznym tempie. Dlatego użytkownik musi napisać kod, który działa, gdy użytkownik przejdzie z jednego klucza na następny.

Przykład: AEAD

Rozważ klucze zestawu AEAD, który zawiera wiele kluczy dla prymitywu AEAD. Jak już wspomnieliśmy, każdy klucz określa 2 funkcje: \(\mathrm{Enc}\) i  \(\mathrm{Dec}\). Zestaw kluczy określa teraz też 2 nowe funkcje: \(\mathrm{Enc}\) i  \(\mathrm{Dec}\) . Funkcja \(\mathrm{Enc}\) jest równa funkcji \(\mathrm{Enc}\) klucza głównego zestawu kluczy, a funkcja \(\mathrm{Dec}\) próbuje odszyfrować za pomocą wszystkich kluczy, przechodząc przez nie w określonej kolejności (jak Tink poprawia wydajność tego procesu, wyjaśniamy poniżej).

Warto zauważyć, że zestawy kluczy to pełne klucze: \(\mathrm{Enc}\) zawierają one pełny opis funkcji \(\mathrm{Enc}\) i\(\mathrm{Dec}\) , które zostały użyte. Oznacza to, że użytkownicy mogą napisać klasę, która przyjmuje jako dane wejściowe KeysetHandle, co oznacza, że klasa potrzebuje pełnego opisu obiektów \(\mathrm{Enc}\) , aby działać prawidłowo. \(\mathrm{Dec}\) Umożliwia to użytkownikowi pisanie interfejsów API, które informują, że do użycia tej klasy musisz podać opis prymitywu kryptograficznego.

Rotacja kluczy

Użytkownik Tink pisze program, który najpierw pobiera zestaw kluczy z serwisu KMS, a potem tworzy obiekt AEAD z tego zestawu kluczy, a na koniec używa tego obiektu do szyfrowania i odszyfrowywania tekstów zaszyfrowanych.

Taki użytkownik jest automatycznie przygotowany do rotacji kluczy i przełączania algorytmów, jeśli jego obecny wybór nie spełnia już standardów.

Należy jednak zachować ostrożność podczas wdrażania rotacji kluczy: Po pierwsze, KMS powinien dodać nowy klucz do zestawu kluczy (ale nie ustawiać go jeszcze jako głównego). Następnie nowy zestaw kluczy musi zostać wdrożony we wszystkich plikach binarnych, aby każdy plik binarny korzystający z tego zestawu miał najnowszy klucz. Dopiero wtedy nowy klucz powinien stać się kluczem głównym, a uzyskany zestaw kluczy zostanie ponownie rozpowszechniony do wszystkich binarnych plików używających tego zestawu.

Identyfikatory kluczy w szyfrze

Przyjrzyjmy się jeszcze raz przykładowi zestawu kluczy AEAD. Jeśli nie zastosujesz zabezpieczeń, odszyfrowanie szyfrogramu wymaga, aby Tink próbował odszyfrować go za pomocą wszystkich kluczy z zestawu kluczy, ponieważ nie ma możliwości ustalenia, który klucz został użyty do zaszyfrowania zestawu kluczy. Może to spowodować znaczne obciążenie wydajności.

Dlatego Tink pozwala dodać do szyfrów prefiks w postaci 5-bajtowego ciągu utworzonego na podstawie identyfikatora. Zgodnie z zasadami dotyczącymi „pełnych kluczy” opisanymi powyżej ten prefiks jest częścią klucza, a wszystkie teksty zaszyfrowane za pomocą tego klucza powinny zawierać ten prefiks. Podczas tworzenia kluczy użytkownicy mogą wybrać, czy klucz ma używać takiego prefiksu, czy też ma być używany w formacie szyfrowanym bez prefiksu.

Gdy klucz znajduje się w kluczowcu, Tink oblicza ten tag na podstawie identyfikatora klucza w kluczowcu. Fakt, że identyfikatory są unikalne2 w ramach klucza, oznacza, że tagi są unikalne. Dlatego, jeśli używane są tylko oznaczone klucze, nie ma spadku wydajności w porównaniu z odszyfrowaniem za pomocą pojedynczego klucza: Tink musi wypróbować tylko jeden z kluczy podczas odszyfrowywania.

Ponieważ jednak tag jest częścią klucza, oznacza to również, że klucz może być częścią klucza zbiorczego tylko wtedy, gdy ma określony identyfikator. Ma to pewne konsekwencje przy opisie implementacji kluczowych obiektów w różnych językach.


  1. Niektóre części Tink nadal traktują zestawy kluczy jako jeden zestaw. Należy jednak to zmienić. Jest to ważne, ponieważ kolejność jest ogólnie ważna: zastanów się na przykład nad typowym cyklem życia rotacji kluczy w przypadku EAD. Najpierw do zestawu kluczy dodawany jest nowy klucz. Ten klucz nie jest jeszcze ustawiony jako główny, ale jest aktywny. Ten nowy zestaw kluczy jest wprowadzany we wszystkich plikach binarnych. Gdy wszystkie pliki binarne znają nowy klucz, staje się on kluczem głównym (w tym momencie używanie tego klucza jest bezpieczne). W tym drugim kroku rotacja kluczy musi znać ostatni dodany klucz. 

  2. Ze względu na zgodność z biblioteką wewnętrzną Google Tink umożliwia tworzenie zestawów kluczy, w których identyfikatory się powtarzają. W przyszłości ta opcja zostanie usunięta.