Tink Wire-Format

Auf dieser Seite wird das Wire-Format von Tink für Schlüssel und primitive Ausgabe beschrieben. Die Dokumentation richtet sich an Kryptologen, die Tink zusätzliche Sprachen hinzufügen möchten, und an Entwickler anderer kryptografischer Hochsprachenbibliotheken, die einen drahtkompatiblen Modus benötigen. Sie ist nicht für alle Altersgruppen geeignet.

Schlüsselsatz-Serialisierung

Tink verwendet Google Protobuf, um seine Schlüsselsätze zu serialisieren.

  • Ein binär serialisierter Schlüsselsatz ist ein serialisierter Keyset-Prototyp, der in tink.proto definiert ist. Das Wertattribut „KeyData“ eines Schlüssels ist ein serialisierter Prototyp des entsprechenden Schlüsseltyps.
  • Ein JSON-serialisiertes Keyset ist ein Keyset-Prototyp, der im JSON-Format serialisiert ist. Der Wert „KeyData“ ist weiterhin ein binär serialisiertes Proto.
  • Ein verschlüsselter Schlüsselsatz ist ein serialisierter EncryptedKeyset-Prototyp, der in tink.proto definiert ist. Es enthält ein verschlüsseltes binär serialisiertes Keyset und optional einige unverschlüsselte KeysetInfo-Metadaten.

Tink-Ausgabepräfix

Die meisten Tink-Primitive unterstützen ein 5-Byte-Ausgabepräfix, das aus folgenden Elementen besteht:

  • 1-Byte-Version: 0x01
  • Hinweis zum 4-Byte-Schlüssel: Dies ist die Schlüssel-ID des verwendeten Schlüssels.

Einige ältere Schlüssel unterstützen möglicherweise auch das Versionsbyte 0x00.

Dieses Präfix ist nicht authentifiziert und kann nicht zu Sicherheitszwecken verwendet werden. Tink verwendet sie als Hinweis, um die Entschlüsselung oder Überprüfung zu beschleunigen.

AEAD

Im Allgemeinen formatiert Tink AEAD-Chiffren so:

prefix || IV || ciphertext || tag

sofern im entsprechenden RFC nicht anders angegeben. prefix ist entweder leer oder ein 5-Byte-Tink-Ausgabepräfix.

AES-CTR-HMAC

Bei AES-CTR-HMAC berechnet Tink den MAC mit den zugehörigen Daten (AD) so:

AD || IV || ciphertext || bitlen(AD)

wobei bitlen(AD) die Länge von AD in Bits ist, dargestellt als vorzeichenlose 64‑Bit-Big-Endian-Ganzzahl. Dieses HMAC-Schema folgt dem Entwurf für AES-CBC-HMAC von Mcgrew.

Deterministische AEAD

Tink implementiert RFC 5297 für AES-SIV und platziert den synthetischen Initialisierungsvektor (SIV) am Anfang des Geheimtexts. Das Primitive kann ein 5-Byte-Tink-Ausgabepräfix hinzufügen.

Während RFC 5297 eine Liste verknüpfter Daten unterstützt, unterstützt Tink nur genau ein verknüpftes Datenelement, was einer Liste mit einem Element in RFC 5297 entspricht. Leere verknüpfte Daten sind eine Liste mit einem leeren Element und keine leere Liste.

Streaming AEAD

Weitere Informationen finden Sie unter AES-CTR HMAC und AES-GCM-HKDF.

Umschlagverschlüsselung

Bei der Umschlagverschlüsselung werden die Daten mit einem Datenverschlüsselungsschlüssel DEK mithilfe der AEAD-Primitiven von Tink verschlüsselt. So funktioniert die Verschlüsselung:

  • Anhand einer bestimmten Schlüsselvorlage (oder Schlüsselparameter) wird eine neue DEK generiert.
  • Der DEK wird in einen Byte-String serialisiert. Das Serialisierungsformat der Protokollpufferserialisierung des Schlüsseltyps „proto“. Dies ist beispielsweise eine serialisierte AesGcmKey-Protokollpuffernachricht, die in aes_gcm.proto für DEK vom Typ AES GCM definiert ist. Informationen zum Serialisieren eines Protokollpuffers finden Sie unter Protokollpufferserialisierung.
  • Die serialisierte DEK wird von einem externen Anbieter (z. B. GCP) in eine encrypted DEK verschlüsselt.
  • Mit der DEK wird der Klartext mit den zugehörigen Daten in ciphertext verschlüsselt. ciphertext hat also genau dasselbe Format wie die AEAD-Primitivstruktur, die der DEK entspricht.

Das Ausgabeformat der Umschlagverschlüsselung sieht so aus:

encrypted DEK length || encrypted DEK || ciphertext

encrypted DEK length hat eine Größe von 4 Byte und speichert die Länge von encrypted DEK als 32‑Bit-Big-Endian-Ganzzahl.

MAC

Tink hält sich an die entsprechenden RFCs. Primitive können dem Tag ein 5-Byte-Tink-Ausgabepräfix hinzufügen.

PRF-Set

Tink hält sich an die entsprechenden RFCs. Der Schlüsseltyp für PRF-Set unterscheidet sich vom MAC-Schlüsseltyp desselben Algorithmus, da er die Ausgabelänge nicht enthält. PRF-Set-Schlüsseln wird nie ein Tink-Ausgabepräfix hinzugefügt. So wird sichergestellt, dass die Ausgabe tatsächlich eine PRF ist.

Hybridverschlüsselung

Das allgemeine Wire-Format für die hybride Tink-Verschlüsselung ist:

prefix || encapsulated_key || encrypted_data

prefix ist entweder leer oder ein 5-Byte-Tink-Ausgabepräfix. Jeder Schlüsseltyp enthält Informationen dazu, wie viele Bytes geparst werden müssen und wie diese Bytes aus encapsulated_key geparst werden.

HPKE (Hybrid Public Key Encryption)

Tink folgt dem HPKE-Standard, der in RFC 9180 definiert ist. Eine HPKE-Chiffrensuite umfasst die folgenden drei Primitive.

  • Key Encapsulation Mechanism (KEM)
  • Schlüsselableitungsfunktion (KDF)
  • Authentifizierte Verschlüsselung mit verknüpften Daten (Authenticated Encryption with Associated Data, AEAD)

Der HPKE-Standard definiert in RFC 9180, Abschnitt 10 kein allgemeines Bitübertragungsformat. In der HPKE-Implementierung von Tink werden die folgenden Werte für encapsulated_key und encrypted_data verwendet.

  • encapsulated_key
    • Der serialisierte öffentliche Schlüssel des Absenders
    • Definiert als enc in RFC 9180, Abschnitt 4.1
    • Format wird durch die verwendete HPKE KEM bestimmt
  • encrypted_data
    • Geheimtext und Tag (z.B. ciphertext || tag ohne IV)
    • Definiert als ct in RFC 9180, Abschnitt 4
    • Format wird durch die verwendete HPKE-AEAD bestimmt
X25519 Diffie-Hellman-basierte KEM

Bei X25519-DHKEMs ist der Wert enc der 32-Byte-Diffie-Hellman-öffentliche Schlüssel des Absenders.

ECIES-AEAD-HKDF

Bei der ECIES-AEAD-HKDF-Implementierung von Tink ist encapsulated_key die Ausgabe des Key Encapsulation Mechanism (KEM) und encrypted_data die Ausgabe des Data Encapsulation Mechanism (DEM).

KEM

Je nach Schlüsseltyp verwendet Tink komprimierte und nicht komprimierte elliptische Kurvenpunkte gemäß den Codierungsstandards RFC 8422/ANSI.X9-62.2005. Bei nicht komprimierten Punkten folgt auf das Byte 0x04 die x- und die y-Koordinate als Ganzzahlen mit fester Größe. Für komprimierte Koordinaten werden das Byte 0x02 oder 0x03 und die x-Koordinate als Ganzzahl mit fester Größe verwendet. Für X25519 wird die Definition von RFC 7748 verwendet (x-Koordinate als Ganzzahl mit fester Größe).

DEM

Für encrypted_data verwendet Tink dasselbe Format wie für AEAD. Dazu gehört auch die Angabe einer IV.

Schlüsselableitung

Zuerst wird die x-Koordinate x_ss des gemeinsamen Punkts berechnet. Der Schlüssel für die AEAD wird dann auf Folgendes festgelegt:

HKDF(ikm = encapsulated_key || x_ss, salt = salt_of_key, info = context_info, length = dem_key_size)

Dabei ist encapsulated_key die vollständige KEM-Ausgabe in Form von Bytes.

Digitale Signaturen

Tink hält sich an die entsprechenden RFCs. Primitive können dem generierten Tag ein 5-Byte-Tink-Ausgabepräfix hinzufügen.

ECDSA

Je nach dem Wert des Felds EcdsaSignatureEncoding im Schlüssel hat eine ECDSA-Signatur das Format IEEE P1363 oder ASN.1 DER.

Das Format der IEEE P1363-Signatur ist r || s, wobei r und s mit Nullen aufgefüllt sind und dieselbe Größe in Byte wie die Ordnung der Kurve haben. Bei der NIST P-256-Kurve werden r und s beispielsweise auf 32 Byte mit Nullen aufgefüllt.

Die DER-Signatur wird mit ASN.1 codiert:

ECDSA-Sig-Value :: = SEQUENCE { r INTEGER, s INTEGER }

Insbesondere gilt Folgendes:

0x30 || totalLength || 0x02 || r's length || r || 0x02 || s's length || s

Tink folgt den Best Practices für die Signaturprüfung und akzeptiert nur DER-codierte ECDSA-Signaturen. Alternative BER-codierte Signaturen sind ungültig.

So lassen sich Angriffe auf die Signaturveränderbarkeit verhindern, die häufig auf Kryptowährungssysteme abzielen.