Na tej stronie opisujemy format Tink dla kluczy i danych wyjściowych typu primitive. Dokumentacja jest przeznaczona dla kryptografów, którzy chcą dodać do Tink dodatkowe języki, oraz dla osób zarządzających innymi bibliotekami kryptograficznymi wysokiego poziomu, które chcą mieć tryb zgodny z protokołem. Nie jest przeznaczona dla wszystkich odbiorców.
Serializacja zbioru kluczy
Tink używa protokołu Google protobuf do serializacji zestawów kluczy.
- Binarny serializowany zestaw kluczy to serializowany proto zestawu kluczy zdefiniowany w pliku tink.proto. Właściwość KeyData klucza to serializowany protokół odpowiedniego typu klucza.
- Zserializowany w formacie JSON zestaw kluczy to protokół Keyset zserializowany w formacie JSON. Pamiętaj, że wartość KeyData jest nadal binarnym serializowanym proto.
- Zaszyfrowany zbiór kluczy to zserializowany protokół EncryptedKeyset zdefiniowany w pliku tink.proto. Zawiera zaszyfrowany binarny serializowany zestaw kluczy i opcjonalnie metadane KeysetInfo bez szyfrowania.
Prefiks wyjściowy Tink
Większość typów pierwotnych Tink obsługuje 5-bajtowy prefiks wyjściowy składający się z:
- Wersja 1-bajtowa:
0x01 - 4-bajtowa wskazówka dotycząca klucza: identyfikator użytego klucza.
Niektóre starsze klucze mogą też obsługiwać bajt wersji 0x00.
Prymityw Prehash używa bajtu wersji 0xff. Więcej informacji znajdziesz w sekcji Wartości wstępnego haszowania w zewnętrznym Mu ML-DSA.
Pamiętaj, że te prefiksy nie są uwierzytelnione i nie można na nich polegać w celach związanych z bezpieczeństwem. Tink używa ich jako wskazówki, aby przyspieszyć odszyfrowywanie lub weryfikację albo wybrać klucz podpisu w scenariuszu podpisywania wstępnego skrótu.
AEAD
Ogólnie rzecz biorąc, Tink formatuje teksty zaszyfrowane AEAD w ten sposób:
prefix || IV || ciphertext || tag
chyba że w odpowiednim dokumencie RFC określono inaczej. prefix jest puste lub zawiera 5-bajtowy prefiks wyjściowy Tink.
AES-CTR-HMAC
W przypadku AES-CTR-HMAC Tink oblicza kod MAC z danymi powiązanymi (AD) w ten sposób:
AD || IV || ciphertext || bitlen(AD)
gdzie bitlen(AD) to długość AD w bitach reprezentowana jako 64-bitowa liczba całkowita bez znaku w formacie big-endian. Ten schemat HMAC jest zgodny z projektem AES-CBC-HMAC autorstwa Mcgrewa.
Deterministyczne AEAD
Tink implementuje RFC 5297 dla AES-SIV, umieszczając syntetyczny wektor inicjujący (SIV) na początku tekstu zaszyfrowanego. Typ pierwotny może dodać 5-bajtowy prefiks danych wyjściowych Tink.
Chociaż RFC 5297 obsługuje listę powiązanych danych, Tink obsługuje tylko dokładnie 1 powiązany element danych, który w RFC 5297 odpowiada liście z 1 elementem. Puste dane powiązane to lista z 1 pustym elementem, a nie pusta lista.
Strumieniowe AEAD
Zobacz AES-CTR HMAC i AES-GCM-HKDF.
Szyfrowanie kopertowe
Szyfrowanie kopertowe szyfruje dane za pomocą klucza szyfrującego dane DEK przy użyciu
prymitywów AEAD Tink. Szyfrowanie działa w ten sposób:
- Generowany jest nowy
DEKprzy użyciu danego szablonu klucza (lub parametrów klucza). - Pole
DEKjest serializowane do postaci ciągu bajtów. Format serializacji, czyli serializacja bufora protokołu typu klucza proto. Na przykład jest to zserializowana wiadomość bufora protokołuAesGcmKeyzdefiniowana w pliku aes_gcm.proto dla klucza DEK typu AES GCM. Informacje o tym, jak serializować bufor protokołu, znajdziesz w sekcji Serializacja bufora protokołu. - Zserializowany obiekt
DEKjest szyfrowany przez zewnętrznego dostawcę (np. GCP) do postaciencrypted DEK. - Funkcja
DEKsłuży do szyfrowania tekstu jawnego za pomocą powiązanych danych wciphertext. Dlategociphertextma dokładnie taki sam format jak pierwotna funkcja AEAD odpowiadającaDEK.
Format wyjściowy szyfrowania kopertowego jest następujący:
encrypted DEK length || encrypted DEK || ciphertext
Pole encrypted DEK length ma 4 bajty i zawiera długość pola encrypted DEK
w postaci 32-bitowej liczby całkowitej w formacie big-endian.
MAC
Tink jest zgodny z odpowiednimi RFC. Typy pierwotne mogą dodawać do tagu 5-bajtowy prefiks danych wyjściowych Tink.
Zestaw PRF
Tink postępuje zgodnie z odpowiednimi RFC. Pamiętaj, że w przypadku funkcji PRF typ klucza różni się od typu klucza MAC tego samego algorytmu tym, że nie zawiera długości danych wyjściowych. Klucze PRF Set nigdy nie dodają prefiksu wyjściowego Tink. Dzięki temu dane wyjściowe są rzeczywiście funkcją PRF.
Szyfrowanie hybrydowe
Ogólny format przesyłania w przypadku szyfrowania hybrydowego Tink jest następujący:
prefix || encapsulated_key || encrypted_data
prefix jest puste lub zawiera 5-bajtowy prefiks wyjściowy Tink. Każdy typ klucza zawiera informacje o tym, ile bajtów należy przeanalizować i jak to zrobić w przypadku encapsulated_key.
HPKE (Hybrid Public Key Encryption)
Tink jest zgodny ze standardem HPKE zdefiniowanym w RFC 9180. Zestaw szyfrów HPKE obejmuje te 3 podstawowe elementy:
- Mechanizm hermetyzacji klucza (KEM)
- Funkcja derywacji klucza (KDF)
- Szyfrowanie uwierzytelnione z danymi powiązanymi (AEAD)
Standard HPKE nie definiuje ogólnego formatu transmisji w RFC 9180, sekcja 10. Implementacja HPKE w Tink używa tych wartości:encapsulated_key i encrypted_data.
encapsulated_key- Zserializowany klucz publiczny nadawcy
- Zdefiniowano jako
encw sekcji 4.1 standardu RFC 9180 - Format określony przez użyty algorytm HPKE KEM
encrypted_data- Szyfrogram i tag (np.
ciphertext || tagbez IV) - Zdefiniowane jako
ctw RFC 9180, sekcja 4 - Format zależy od użytego konkretnego algorytmu HPKE AEAD.
- Szyfrogram i tag (np.
Mechanizm kodowania kluczy oparty na protokole Diffiego-Hellmana X25519
W przypadku algorytmów DHKEM X25519 wartość enc to 32-bajtowy klucz publiczny Diffiego-Hellmana nadawcy.
ECIES-AEAD-HKDF
W przypadku implementacji ECIES-AEAD-HKDF w Tink encapsulated_key to dane wyjściowe mechanizmu hermetyzacji kluczy (KEM), a encrypted_data to dane wyjściowe mechanizmu hermetyzacji danych (DEM).
KEM
W zależności od typu klucza Tink używa skompresowanych i nieskompresowanych punktów krzywej eliptycznej zgodnie ze standardami kodowania RFC 8422/ANSI.X9-62.2005. W przypadku nieskompresowanych punktów po bajcie 0x04 następuje współrzędna x i współrzędna y jako liczby całkowite o stałym rozmiarze. W przypadku skompresowanych współrzędnych używany jest bajt 0x02
lub 0x03 oraz współrzędna x jako liczba całkowita o stałym rozmiarze. W przypadku X25519,
używana jest definicja z dokumentu RFC 7748 (współrzędna x jako liczba całkowita o stałym rozmiarze).
DEM
W przypadku encrypted_data Tink używa tego samego formatu co AEAD. Obejmuje to określenie wektora inicjującego.
Derywacja klucza
Najpierw obliczana jest współrzędna x x_ss udostępnionego punktu. Klucz do AEAD jest następnie ustawiany na:
HKDF(ikm = encapsulated_key || x_ss, salt = salt_of_key, info = context_info, length = dem_key_size)
gdzie encapsulated_key to pełne dane wyjściowe KEM w bajtach.
Podpisy cyfrowe
Tink postępuje zgodnie z odpowiednimi RFC. Typy pierwotne mogą dodawać do generowanego tagu 5-bajtowy prefiks wyjściowy Tink.
ECDSA
W zależności od pola EcdsaSignatureEncoding w kluczu format podpisu ECDSA to IEEE P1363 lub ASN.1 DER.
Format podpisu IEEE P1363 to r || s, gdzie r i s są dopełnione zerami i mają taki sam rozmiar w bajtach jak rząd krzywej. Na przykład w przypadku krzywej NIST P-256 wartości r i s są uzupełniane zerami do 32 bajtów.
Podpis DER jest kodowany za pomocą funkcji ASN.1:
ECDSA-Sig-Value :: = SEQUENCE { r INTEGER, s INTEGER }
W szczególności kodowanie to:
0x30 || totalLength || 0x02 || r's length || r || 0x02 || s's length || s
Tink stosuje sprawdzone metody weryfikacji podpisu, akceptując tylko podpisy ECDSA zakodowane w formacie DER (podpisy zakodowane w formacie BER są nieprawidłowe).
Pomaga to zapobiegać atakom polegającym na zmianie sygnatury, które często wpływają na systemy kryptowalut.
Wartości prehash ML-DSA z zewnętrzną wartością mu
Funkcja Prehash przekształca wiadomość w wartość wstępnego haszowania, którą następnie podpisuje funkcja SignPrehash. W przypadku ML-DSA w trybie External Mu, zgodnie z opisem w RFC 9881, wartość prehash ma 69 bajtów i ten układ:
0xff || key_id (4 bytes, big-endian) || mu (64 bytes)
muto reprezentacja komunikatu ML-DSA obliczana jakoSHAKE256(tr || 0x00 || 0x00 || message, 64), gdzietrto 64-bajtowy skrót klucza publicznego, pierwszy znak0x00to separator domeny FIPS 204 dla czystego ML-DSA, a drugi znak0x00to długość (pustego) ciągu kontekstowego. Ponieważtrjest wyprowadzany z klucza publicznego,mujest z nim powiązany kryptograficznie, chociaż sprawdzenie tego powiązania wymaga oryginalnej wiadomości.- 5-bajtowy prefiks to ramka Tink, która nie jest częścią
mu. Powiązuje wartość prehash z określonym kluczem, dzięki czemu funkcja SignPrehash wie, którego klucza użyć do podpisania, i może odrzucić wartość prehash, dla której nie ma klucza. Prefiks to zwykłe metadane, które nie są powiązane z niczym kryptograficznie: każdy może je zmienić.
Podpisywanie odrzuca wszystkie dane wejściowe, które nie mają dokładnie 69 bajtów, nie zaczynają się od 0xff lub których identyfikator klucza nie pasuje do włączonego klucza w zestawie kluczy.