Als Nächstes definieren wir (informeller, aber förmlicher) zwei wichtige die in Tink verwendete Sprache, das primitive und die Schnittstelle.
Schlicht
Ein Primitiv ist ein mathematisches Objekt, das allen Algorithmen entspricht um eine Aufgabe sicher auszuführen. Zum Beispiel besteht das AEAD-Primitive aus allen Verschlüsselungsalgorithmen, die die von Tink geforderten Sicherheitseigenschaften erfüllen eines Aead.
Wir betonen, dass Primitive nicht an eine Programmiersprache oder Methode und darauf zugreifen. Stattdessen sollte man sich das Primitive mathematischem Objekt. Wenn wir z. B. AEAD in Betracht ziehen, besteht aus Funktionspaaren, von denen eine die Verschlüsselung durchführt und die führt eine Entschlüsselung durch.
Interfaces
Über eine Schnittstelle gewähren wir Nutzern Zugriff auf eine Primitive.
Wir gehen beispielsweise davon aus, dass Tink in Zukunft eine Mac
-Oberfläche bereitstellen wird.
sondern auch eine StreamingMac
-Schnittstelle, mit der
die nicht direkt in den Arbeitsspeicher geladen werden.
Beachten Sie, dass wir hier ausdrücklich zwischen Schnittstellen und Primitiven unterscheiden. Dies sollte deutlich, dass das mathematische Objekt, dem diese beiden Oberflächen sind die gleichen Zugriffsrechte.
Formale Definitionen
Für die meisten Leser sind die obigen intuitiven Erklärungen wahrscheinlich ausreichend. Dennoch sind wir der Meinung, dass es manchmal wichtig sein kann, Definitionen dieser Konzepte.
Kryptografische Funktionen
Das Konzept einer kryptografischen Funktion ist nicht so wichtig wie das um sie formal zu definieren.
- Kryptografische Funktion
Eine kryptografische Funktion ist eine Zuordnung
\[ f: {\bf K} \times {\bf R} \times {\bf I} \to {\bf O}\]
aus einer Menge \({\bf K}\) (dem Schlüsselbereich), einer Menge \({\bf R} = \{0,1\}^{\infty}\) (Zufälligkeit, von der wir annehmen, dass sie die Menge unendlicher Bitstrings ist) und ein set \({\bf I}\) (Eingaberaum) auf ein Set \({\bf O}\) (Ausgabebereich).
Es wird später klar, warum wir einen bestimmten Zufälligkeitsparameter hinzugefügt haben.
Wir zeigen eine Möglichkeit, wie diese Konzepte AES-GCM. Für jede gültige Schlüsselgröße \(s_k\), Nonce-Größe \(s_n\)und Tag-Größe \(s_t\), besteht AES-GCM aus zwei kryptografischen Funktionen, einer für Verschlüsselung und einer für Entschlüsselung. Beide haben denselben Schlüsselbereich \({\bf K} = \{0,1\}^{s_k}\).
Für die Verschlüsselungsfunktion \(\mathrm{Enc}\)werden die ersten \(s_n\) Bits von zur Auswahl der Nonce verwendet.
Bezeichnet \({\bf B} = \{0,1\}^8\) ein Byte. Der Eingaberaum der Verschlüsselungsfunktion besteht aus den Paaren \({\bf I} = {\bf B}^{*} \times {\bf B}^{*}\) von Paaren von Bytestrings beliebiger Länge. Das erste Element ist die Botschaft, das zweite Element die damit verbundenen Daten. Der AES-GCM-Standard hat eine Obergrenze für die Länge Eingaben möglich. Wir bevorzugen jedoch beliebige Längen und fügen stattdessen eine spezielle Fehlersymbol \(\bot\) in den Ausgabebereich ein. Der Ausgaberaum wird dann zu \({\bf O} = {\bf B}^* \cup \{\bot\}\), wo wir das Ergebnis von erfolgreiche Berechnungen als Verkettung \((\mathrm{IV} \| \mathrm{ciphertext} \| \mathrm{tag})\) wie im Standard \(\bot\), falls eine Eingabe zu lang ist. Bei einem festen Schlüssel Verschlüsselungsfunktion erhält den Typ \(\mathrm{Enc}_k : {\bf R} \times {\bf B}^* \times {\bf B}^* \rightarrow {\bf B}^* \cup \{\bot\}\).
Bei der Entschlüsselungsfunktion \(\mathrm{Dec}\) ist der Schlüsselbereich derselbe. Die Eingaberaum ist zufällig gleich: \({\bf I} ={\bf B}^* \times {\bf B}^*\), Das erste Element ist aber die Ausgabe der Verschlüsselungsfunktion. während die zweite noch die zugehörigen Daten enthält.
Auch der Ausgaberaum ist derselbe \({\bf O} = {\bf B}^* \cup \{\bot\}\) (auch wieder ein Zufall). Die Interpretation ist etwas anders, as \(\bot\) bezeichnet normalerweise einen Authentifizierungsfehler (aber es ist auch der Fehler, für den Fall, dass eine Eingabe zu lang ist).
Wir betonen, dass die oben genannte Formulierung nicht die einzige Möglichkeit ist, den Prozess zu formalisieren. Standard. Sie könnten z. B. die Nonce als Teil der Eingabe betrachten, aus dem Zufall lesen (was zu einer ganz anderen Primitivität führt). Alternativ könnte man die Ausgabe als ein Dreifach definieren, das die Nonce enthält, den Geheimtext und das Tag (anstatt die Verkettung). Oder man könnte den Schlüsselraum (etwas willkürlich) auf \({\bf K} = \{0,1\}^{128} \cup \{0,1\}^{256}\)
- Kryptografischer Algorithmus:
Ein (symmetrischer) kryptografischer Algorithmus ist ein Tupel
\[(f_1, ... f_k)\]
von kryptografischen Funktionen, wobei alle Funktionen den gleichen Schlüsselraum haben. Die type des kryptografischen Algorithmus ist das Tupel \((({\bf I}_1, {\bf O}_1), \ldots, ({\bf I}_k, {\bf O}_k))\).
Beispiel: Für jedes gültige Dreifach \((s_k, s_n, s_t)\) von Schlüssel, Nonce und Tag ist AES-GCM\({}_{s_k, s_n, s_t}\) ein kryptografischer Algorithmus zwei Funktionen \(\mathrm{Enc}\) und \(\mathrm{Dec}\) oben beschrieben.
Primitive und Schnittstellen
Als Nächstes definieren wir ein kryptografisches Primitiv.
- Schlicht
- Eine Primitive ist eine Reihe kryptografischer Algorithmen, in denen alle Algorithmen haben denselben Typ \((({\bf I}_1, {\bf O}_1), \ldots, ({\bf I}_k, {\bf O}_k))\)und die Schlüsselräume der Algorithmen sind paarweise disjunkt.
Betrachten Sie als Beispiel das \(\mathrm{AEAD}\) Primitive in Tink. Es enthält mehrere Algorithmen, darunter AES-GCM für die Schlüsselgrößen 128 und 256 Bit, mit Nonce mit 96 Bit, AES-EAX mit einigen Schlüsselgrößen und XChaCha20Poly1305. Sie haben Disjunkte Schlüsselräume, aber alle bieten dieselben kryptografischen Funktionen \(\mathrm{Enc}\) und \(\mathrm{Dec}\). (Wir sehen in irgendeiner Form keinen Zweck, in dieser formellen Diskussion die unterschiedlichen Schlüsselgrößen von AES-GCM minimieren, Natürlich könnte man das tun).
Primitive definieren
Üblicherweise werden Primitive zuerst die Eigenschaften eines Kryptografiefunktionen und dann einfach nur die Primitive als für solche Algorithmen.
Für AEAD würden wir zum Beispiel sagen, dass \(\mathrm{Dec}_k(\mathrm{Enc}_k(m, a), a) = m\) „immer“ ist. zufrieden (außer wenn der Klartext \(m\) zu long). Darüber hinaus haben wir Sicherheitseigenschaften: zum Beispiel für ist die Verschlüsselung absolut sicher.
Das AEAD-Primitive ist dann einfach die Menge aller kryptografischen Algorithmen, diese Eigenschaften erfüllen. Wenn wir also in der Praxis eine bestimmte privilegiert wird, definieren wir sie anhand von Eigenschaften. Wir stellen keine Liste mit wie die Definition verrät.
Interfaces
Eine Schnittstelle in Tink bietet Zugriff auf eine Primitive, also so, dass sie ein Element des Ausgaberaums aus dem Eingaberaum zu berechnen. Beispiel: Betrachten Sie die AEAD-Schnittstelle in Java:
public interface Aead {
byte[] encrypt(byte[] plaintext, byte[] associated_data) throws GeneralSecurityException;
byte[] decrypt(byte[] ciphertext, byte[] associated_data) throws GeneralSecurityException;
}
Beachten Sie, dass wir keinen Zugriff auf die Zufälligkeit gewähren. Stattdessen können Nutzer Elemente des Eingaberaums bereitstellen. Die Verhinderung des Zugriffs auf die Zufälligkeit ist von mit Bedacht vor.1
Tink bietet manchmal mehrere Oberflächen für ein einzelnes Primitiv.
Das kann sehr nützlich sein, da die Anforderungen manchmal unterschiedlich sind. Trotzdem
Das hat ihren Preis: Im Allgemeinen gilt: Je mehr Oberflächen ein Nutzer anbietet, desto niedriger ist die
Interoperabilität ist. Stellen Sie sich zum Beispiel vor,
dass jemand eine Bibliothek auf Basis von Tink schreibt, bei der
Aead
-Objekt (um etwas intern zu verschlüsseln). Wenn Tink zu viele
Schnittstellen zur \(\mathrm{AEAD}\) Primitiven erstellen, sind die Chancen hoch
dass die Nutzenden
verfügt über keine Instanz, die für den vom Nutzer ausgewählten Schlüssel und den
in einer Bibliothek. Daher ist das Hinzufügen weiterer Oberflächen ein Kompromiss.
-
AEAD-Chiffren haben die Eigenschaft, dass sie sicher sind. gegen ausgewählte Geheimtextangriffe, was nur garantiert wird, wenn es keine Wiederverwendung der Nonce. Die Aead-Benutzeroberfläche in Tink ist so konzipiert, verhindert die Wiederverwendung von Nonces: Nutzende können keine Nonces als Eingabe für die Verschlüsselung angeben, Stattdessen wird für jeden Verschlüsselungsvorgang nach dem Zufallsprinzip eine neue Nonce generiert. ↩