Zum Hauptinhalt springen

5.2 Encryption and Decryption (Verschlüsselung und Entschlüsselung)

5.2 Encryption and Decryption (Verschlüsselung und Entschlüsselung)

HPKE ermöglicht es, mehrere Verschlüsselungsoperationen basierend auf einer gegebenen Setup-Transaktion durchzuführen. Da die im Setup involvierten öffentlichen Schlüsseloperationen typischerweise teurer sind als symmetrische Verschlüsselung oder Entschlüsselung, erlaubt dies Anwendungen, die Kosten der öffentlichen Schlüsseloperationen zu amortisieren und den Gesamtaufwand zu reduzieren.

Um Nonce-Wiederverwendung zu vermeiden, muss diese Verschlüsselung jedoch zustandsbehaftet sein. Jede der obigen Setup-Prozeduren erzeugt ein rollenspezifisches Kontextobjekt, das die AEAD- und Secret-Export-Parameter speichert. Die AEAD-Parameter bestehen aus:

  • Dem verwendeten AEAD-Algorithmus

  • Einem geheimen Schlüssel

  • Einer Basis-Nonce base_nonce

  • Einer Sequenznummer (anfangs 0)

Die Secret-Export-Parameter bestehen aus:

  • Der verwendeten HPKE-Kryptosuite und

  • Einem exporter_secret, der für die Secret-Export-Schnittstelle verwendet wird (siehe Abschnitt 5.3)

Alle diese Parameter außer der AEAD-Sequenznummer sind konstant. Die Sequenznummer bietet Nonce-Eindeutigkeit: Die für jede Verschlüsselungs- oder Entschlüsselungsoperation verwendete Nonce ist das Ergebnis der XOR-Verknüpfung von base_nonce mit der aktuellen Sequenznummer, kodiert als Big-Endian-Ganzzahl der gleichen Länge wie base_nonce. Implementierungen KÖNNEN eine Sequenznummer verwenden, die kürzer als die Nonce-Länge ist (links mit Null aufgefüllt), MÜSSEN aber einen Fehler auslösen, wenn die Sequenznummer überläuft. Der AEAD-Algorithmus erzeugt Chiffretext, der Nt Bytes länger ist als der Klartext. Nt = 16 für AEAD-Algorithmen, die in diesem Dokument definiert sind.

Die Verschlüsselung ist unidirektional vom Sender zum Empfänger. Der Kontext des Senders kann einen Klartext pt mit zugehörigen Daten aad wie folgt verschlüsseln:

def ContextS.Seal(aad, pt):
ct = Seal(self.key, self.ComputeNonce(self.seq), aad, pt)
self.IncrementSeq()
return ct

Der Kontext des Empfängers kann einen Chiffretext ct mit zugehörigen Daten aad wie folgt entschlüsseln:

def ContextR.Open(aad, ct):
pt = Open(self.key, self.ComputeNonce(self.seq), aad, ct)
if pt == OpenError:
raise OpenError
self.IncrementSeq()
return pt

Jede Verschlüsselungs- oder Entschlüsselungsoperation erhöht die Sequenznummer für den verwendeten Kontext. Die Details zur Pro-Nachricht-Nonce und Sequenznummernerhöhung sind wie folgt:

def Context<ROLE>.ComputeNonce(seq):
seq_bytes = I2OSP(seq, Nn)
return xor(self.base_nonce, seq_bytes)

def Context<ROLE>.IncrementSeq():
if self.seq >= (1 << (8*Nn)) - 1:
raise MessageLimitReachedError
self.seq += 1

Der Kontext des Senders DARF NICHT für die Entschlüsselung verwendet werden. Ebenso DARF der Kontext des Empfängers NICHT für die Verschlüsselung verwendet werden. Höhere Protokolle, die den HPKE-Schlüsselaustausch für allgemeinere Zwecke wiederverwenden, können bei Bedarf separates Schlüsselmaterial unter Verwendung der Secret-Export-Schnittstelle ableiten; siehe Abschnitte 5.3 und 9.8 für weitere Details.

Es liegt in der Verantwortung der Anwendung sicherzustellen, dass Verschlüsselungen und Entschlüsselungen in der richtigen Reihenfolge durchgeführt werden, sodass Verschlüsselungs- und Entschlüsselungs-Nonces übereinstimmen. Wenn ContextS.Seal() oder ContextR.Open() dazu führen würden, dass das seq-Feld überläuft, dann MUSS die Implementierung mit einem Fehler fehlschlagen. (Im folgenden Pseudocode schlägt Context<ROLE>.IncrementSeq() mit einem Fehler fehl, wenn seq überläuft, was dazu führt, dass ContextS.Seal() und ContextR.Open() entsprechend fehlschlagen.) Beachten Sie, dass die internen Seal()- und Open()-Aufrufe dem AEAD-Algorithmus des Kontexts entsprechen.