Tink Wire-Format

Auf dieser Seite wird das Tink-Kabelformat für Schlüssel und die primitive Ausgabe beschrieben. Die Dokumentation richtet sich an Kryptografen, die weitere Sprachen zu Tink hinzufügen möchten, sowie an Administratoren anderer High-Level-Kryptobibliotheken, die einen verbindungskompatiblen Modus wünschen. Sie ist nicht für die allgemeine Zielgruppe gedacht.

Schlüsselsatz-Serialisierung

Tink verwendet zur Serialisierung seiner Schlüsselsätze Google protobuf.

  • Ein binäres serialisiertes Keyset ist ein serialisiertes Keyset-Proto, das in tink.proto definiert ist. Die Werteigenschaft "KeyData" eines Schlüssels ist ein serialisiertes Proto des entsprechenden Schlüsseltyps.
  • Ein JSON-Serialisiertes Keyset ist ein Keyset-Proto, das im JSON-Format serialisiert ist. Beachten Sie, dass der Wert "KeyData" immer noch ein binärer serialisierter Proto-Wert ist.
  • Ein verschlüsseltes Schlüsselsatz ist ein serialisiertes EncryptedKeyst-Proto, das in tink.proto definiert ist. Es enthält ein verschlüsseltes binär serialisiertes Schlüsselsatz und optional einige unverschlüsselte KeysetInfo-Metadaten.

Tink-Ausgabepräfix

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

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

Einige Legacy-Schlüssel unterstützen möglicherweise auch das Versionsbyte 0x00.

Beachten Sie, dass dieses Präfix nicht authentifiziert ist und aus Sicherheitsgründen nicht als Basis verwendet werden kann. Tink verwendet ihn als Hinweis, um die Entschlüsselung oder Überprüfung zu beschleunigen.

AEAD

Im Allgemeinen formatiert Tink AEAD-Geheimtexte als:

prefix || IV || ciphertext || tag

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

AES-CTR-HMAC

Für AES-CTR-HMAC berechnet Tink den MAC mit den zugehörigen Daten (AD) wie folgt:

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

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

Deterministisches AEAD

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

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

AEAD streamen

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

Umschlagverschlüsselung

Bei der Umschlagverschlüsselung werden die Daten mit dem Datenverschlüsselungsschlüssel DEK unter Verwendung der AEAD-Primitive von Tink verschlüsselt. Die Verschlüsselung funktioniert so:

  • Mit einer bestimmten Schlüsselvorlage (oder bestimmten Schlüsselparametern) wird ein neuer DEK generiert.
  • Die DEK wird in einen Bytestring serialisiert. Das Serialisierungsformat ist die Protokollpufferserialisierung des Schlüsseltyps proto. Dies ist beispielsweise eine serialisierte AesGcmKey-Protokollpuffernachricht, die in aes_gcm.proto für einen DEK des Schlüsseltyps AES GCM definiert ist. Weitere Informationen zur Serialisierung eines Protokollpuffers finden Sie unter Protokollpufferserialisierung.
  • Die serialisierte DEK wird von einem externen Anbieter (z. B. GCP) in eine encrypted DEK verschlüsselt.
  • DEK wird verwendet, um den Klartext mit den verknüpften Daten in ciphertext zu verschlüsseln. ciphertext hat also genau das gleiche Format wie die AEAD-Primitive, die dem DEK entsprechen.

Das Ausgabeformat der Umschlagverschlüsselung sieht so aus:

encrypted DEK length || encrypted DEK || ciphertext

encrypted DEK length ist 4 Byte und speichert die Länge von encrypted DEK als 32-Bit-Big-Endian-Ganzzahl.

MAC

Tink folgt den entsprechenden RFCs. Primitives können dem Tag ein 5-Byte-Tink-Ausgabepräfix hinzufügen.

PRF festgelegt

Tink folgt den entsprechenden RFCs. Beachten Sie, dass sich der Schlüsseltyp für „PRF Set“ vom MAC-Schlüsseltyp desselben Algorithmus unterscheidet, da er die Ausgabelänge nicht einbezieht. PRF-Set-Schlüssel fügen niemals ein Tink-Ausgabepräfix hinzu. Dadurch wird sichergestellt, dass die Ausgabe tatsächlich eine PRF-Datei ist.

Hybridverschlüsselung

Das allgemeine Übertragungsformat für die Tink-Hybridverschlüsselung sieht so aus:

prefix || encapsulated_key || encrypted_data

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

HPKE (Hybrid Public Key Encryption)

Tink folgt dem in RFC 9180 definierten HPKE-Standard. Eine HPKE-Chiffrensuite enthält die folgenden drei Primitive.

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

Der HPKE-Standard definiert kein allgemeines Verbindungsformat in RFC 9180, Abschnitt 10. Die HPKE-Implementierung von Tink verwendet die folgenden encapsulated_key- und encrypted_data-Werte.

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

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

ECIES-AEAD-HKDF

Für die 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).

Logo: KEM

Je nach Schlüsseltyp verwendet Tink komprimierte und unkomprimierte Punkte mit elliptischen Kurven gemäß den Codierungsstandards RFC 8422/ANSI.X9-62.2005. Bei unkomprimierten Punkten folgen die Koordinaten x und y dem Byte 0x04 als Ganzzahlen mit fester Größe. Für komprimierte Koordinaten werden das Byte 0x02 oder 0x03 und die Koordinate x als Ganzzahl mit fester Größe verwendet. Für X25519 wird die RFC 7748-Definition 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 so 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 Byte.

Digitale Signaturen

Tink folgt den entsprechenden RFCs. Primitives können dem generierten Tag ein 5-Byte-Tink-Ausgabepräfix hinzufügen.

ECDSA

Abhängig vom Feld EcdsaSignatureEncoding im Schlüssel hat das Format einer ECDSA-Signatur entweder IEEE P1363 oder ASN.1 DER.

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

Die DER-Signatur wird mit ASN.1 codiert:

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

Insbesondere die Codierung sieht so aus:

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

Tink folgt den Best Practices für die Signaturprüfung, indem es nur DER-codierte ECDSA-Signaturen akzeptiert (alternative BER-codierte Signaturen sind ungültig).

Dies trägt dazu bei, Angriffe auf die unterscheidungsfähige Technologie zu verhindern, die häufig Kryptowährungssysteme beeinträchtigen.