Was ist hybride homomorphe Verschlüsselung und ihre Anwendungen
9.2.2023 10:03
TL;DR
Einführung in das Konzept der hybriden homomorphen Verschlüsselung, ihre Anwendungsfälle, eine kurze Formulierung und einige Demonstrationscodes in C++.
Einführung
Anwendungen zum Schutz der Privatsphäre sind heutzutage zu einem wichtigen Thema geworden, da sich die Menschen zunehmend Sorgen um den Schutz ihrer Daten machen, maschinelle Lernanwendungen weit verbreitet sind, die Zugriff auf eine große Menge an Daten benötigen, und neue Vorschriften wie die Allgemeine Datenschutzverordnung (GDPR) gelten, ganz zu schweigen von anderen ethischen und finanziellen Bedenken. Heute werden wir eine neue Technik zur Verbesserung der Privatsphäre kennenlernen, die Hybrid Homomorphic Encryption (HHE), eine Erweiterung der Homomorphic Encryption (HE).
HE ist eine Verschlüsselungstechnik, die es uns ermöglicht, Berechnungen mit verschlüsselten Daten durchzuführen. Eines der Probleme von HE ist jedoch, dass die Chiffretexte um mehrere Größenordnungen größer sind als die entsprechenden Klartexte. HHE zielt darauf ab, dieses Problem zu lösen, indem symmetrische Chiffren mit HE kombiniert werden, um die Größe der Chiffretexte und die erforderlichen Rechenressourcen für die Partei, die die Daten verschlüsselt und sendet (z. B. ein Kunde/Dateneigentümer), auf Kosten teurerer Berechnungen für die Partei, die die Berechnungen mit den verschlüsselten Daten durchführt (z. B. ein Server, ein Cloud-Dienstanbieter oder CSP), zu reduzieren. Daher kann HHE besser geeignet sein als HE, wenn es um das Client-Server-Modell für verschlüsselte Berechnungen geht, insbesondere wenn der Client über begrenzte Rechenressourcen und Internetbandbreite verfügt, z. B. Telefone, IoT-Geräte usw.
Vorteile:
- Ermöglichung von Berechnungen auf verschlüsselten Daten und damit von datenschutzfreundlichen Datenanalysen und Anwendungen
- Verringerung der Größe des Chiffriertextes und damit Verringerung der erforderlichen Rechen- und Bandbreitenressourcen für die Partei, die die Daten besitzt, verschlüsselt und sendet
Benachteiligungen:
- Höherer Rechenaufwand auf dem Gebiet der verschlüsselten Berechnungen
- Derzeit noch auf bestimmte Arten von Daten und Berechnungen beschränkt
Anwendungsfälle
Wie HE kann auch HHE Anwendungen in Bereichen unterstützen, in denen der Datenschutz ein wichtiges Anliegen ist, z. B. im Finanzwesen, im Gesundheitswesen, bei der Regulierung usw. Darüber hinaus kann HHE Anwendungen auf Geräten mit begrenzter Rechenleistung, Speicher und Netzwerkbandbreite, wie z. B. eingebetteten und IoT-Geräten, unterstützen.
Anwendungsbeispiel: Eine Heimüberwachungsanwendung für das Gesundheitswesen, bei der in einem Haushalt installierte IoT-Geräte Bilder (oder andere Signale) aufnehmen, sie verschlüsseln und die verschlüsselten Signale an den Server senden. Der Server führt einen KI-Algorithmus auf den empfangenen verschlüsselten Daten aus und erkennt Anlässe wie z. B. Schlaganfälle. Dann sendet er die verschlüsselten Ergebnisse an das Haushaltsgerät, das für die Entschlüsselung des Ergebnisses verantwortlich ist und nur dann einen Alarm auslöst, wenn das entschlüsselte Ergebnis positiv ist, z. B. wenn Menschen einen Schlaganfall haben. Auf diese Weise kann der Haushalt den Dienst des Servers nutzen, während der Dienstanbieter keine Bilder oder sensiblen Daten des Haushalts sieht.
Kommen wir zu den Berechnungen
Im Folgenden werden einige kurze Formulierungen zu HE und HHE gegeben.
Homomorphe Verschlüsselung
Bevor wir zu HHE kommen, müssen wir zunächst HE verstehen. Mit HE können wir die Daten verschlüsseln und Operationen mit den verschlüsselten Daten durchführen. Das Ergebnis der Entschlüsselung entspricht dem Ergebnis, das bei der Durchführung ähnlicher Operationen mit den entsprechenden Klartextdaten erzielt wird. Um HE besser zu verstehen, verweise ich Sie auf Folgendes Blog-Eintrag von OpenMined.
Sehen wir uns hier die Definition eines homomorphen Verschlüsselungsverfahrens mit öffentlichem Schlüssel an, die aus [1] übernommen wurde und aus 4 Algorithmen besteht:
- HE.KeyGen(1ⁿ) → (pk, sk, evk): Der Algorithmus zur Schlüsselerzeugung. Hier, n ist ein Sicherheitsparameter; pk, sk und evk sind der öffentliche Schlüssel, der geheime Schlüssel und der Auswertungsschlüssel. Wir verwenden pk um die Daten zu verschlüsseln, sk um die verschlüsselten Daten zu entschlüsseln, und evk zur Durchführung von Berechnungen mit verschlüsselten Daten
- HE.Enc(pk, m) → c: Der HE-Verschlüsselungsalgorithmus, wobei m die Klartextdaten und c die HE-verschlüsselten Daten sind
- HE.Eval(evk, f, c₁, c₂, … cᵢ) → c’: Der Bewertungsalgorithmus wobei f ist eine Funktion wie Addition oder Multiplikation, und c‘ ist das HE-verschlüsselte Ergebnis. Wir sollten HE.Dec(sk, c’) = f(m₁, m₂, …, mᵢ)
- HE.Dec(sk, c) → m: Der HE-Entschlüsselungsalgorithmus das dauert sk und der Chiffretext c um die Klartextnachricht zu erstellen m
Hybride homomorphe Verschlüsselung
Anstatt die Daten mit einem HE-Schema zu verschlüsseln, das sehr große Chiffretexte erzeugt (Expansion mehrfacher Ordnung im Vergleich zum Klartext), verschlüsselt HHE sie stattdessen mit einer symmetrischen Chiffre mit dem Expansionsfaktor 1 und sendet die symmetrischen Chiffretexte an den Server. Darüber hinaus muss der Kunde auch eine homomorph verschlüsselte Version seines symmetrischen Schlüssels senden. Nach dem Empfang führt der Server den symmetrischen Entschlüsselungsalgorithmus homomorph aus, um den symmetrischen Chiffretext in einen homomorphen Chiffretext umzuwandeln. Danach kann der Server Berechnungen mit HE-verschlüsselten Daten durchführen. Formal können wir ein HHE-Schema (nach [2]), das aus 5 Algorithmen besteht, wie folgt definieren
- HHE.KeyGen(1ⁿ) →(pk, sk, evk): Dies ist einfach der HE.KeyGen Algorithmus, der den öffentlichen HE-Schlüssel(pk), den geheimen Schlüssel(sk) und den Auswertungsschlüssel(evk) erzeugt
- HHE.Enc(1ⁿ, pk, m): Der HHE-Verschlüsselungsalgorithmus.
Zunächst wird ein symmetrischer Schlüssel erstellt: SYM.KGen(1ⁿ) → k
Mit diesem symmetrischen Schlüssel verschlüsselt er dann die Klartextnachricht m: SYM.Enc(k, m) → cₛ. Hier, cₛ ist der symmetrische Chiffriertext, der an den Server gesendet wird. Beachten Sie, dass cₛ hat die gleiche Größe im Vergleich zu m.
Außerdem, HHE.Enc verschlüsselt ebenfalls homomorph den symmetrischen Schlüssel k mit HE.Enc(pk, k) → cₖ. Folglich ist cₖ der HE-Chiffretext des symmetrischen Schlüssels k, und wird zusammen mit den folgenden Daten an den Server gesendet cₛ - HHE.Decomp(evk, cₖ, cₛ) →. c: Der HHE-Zerlegungsalgorithmus, der den symmetrischen Chiffretext umwandelt cₛ in den HE-Chiffretext c durch homomorphes Auswerten des symmetrischen Entschlüsselungsalgorithmus mit cₖ und cₛ: HE.Eval(evk, f=SYM.Dec, cₖ, cₛ) → c
- HHE.Eval(evk, f, c₁, . . . , cᵢ) → c’: Der HHE-Auswertungsalgorithmus, der einfach HE.Eval(evk, f, c₁, . . . , cᵢ)
- HHE.Dec(sk, c): Der HHE-Entschlüsselungsalgorithmus. Sie gibt einfach zurück HE.Dec(sk, c)
Beachten Sie, dass wir in Schritt 2 Folgendes senden müssen cₖ und cₛ zum Server. Hier, cₖ ist der HE-Chiffretext und kann sehr groß sein. Wir müssen jedoch nur Folgendes senden cₖ einmalig an den Server, z. B. in einer Einrichtungsphase. Der Server kann sie wiederholt in der HHE.Decomp Algorithmus, um neue symmetrische Chiffretexte in entsprechende HE-Chiffretexte umzuwandeln. Dies ist der entscheidende Unterschied zwischen HHE und HE: Anstatt jedes Mal HE-Chiffretexte an den Server zu senden, was sehr bandbreitenintensiv sein kann, sendet HHE stattdessen leichtgewichtige symmetrische Chiffretexte. Durch diesen Trick kann HHE auch auf ressourcenbeschränkten Geräten eingesetzt werden, da symmetrische Chiffren auch sehr leicht zu handhaben sind.
Sind Sie bereit für etwas Code?
Bevor wir in den Code eintauchen, sollten wir uns das Protokoll ansehen, das wir erstellen werden: Wir haben 2 Parteien (einen Client und einen Server), deren Aktionen sich in 3 Hauptschritten zusammenfassen lassen:
- Der Client erzeugt die Schlüssel mit HHE.KeyGen, verschlüsselt die Daten mit HHE.Enc und sendet den symmetrischen Chiffretext seiner Daten(cₛ), den HE-Chiffretext seines symmetrischen Schlüssels(cₖ), die HE-Schlüssel außer dem geheimen Schlüssel sk an den Server.
- Der Server führt den Algorithmus HHE.Decomp und eine lineare Transformation an den HE-verschlüsselten Daten des Kunden mit HHE.Eval durch, erhält das verschlüsselte Ergebnis und sendet es an den Kunden zurück.
- Nach dem Empfang entschlüsselt der Client das Ergebnis mit HHE.Dec und erhält die endgültige Ausgabe im Klartext.
Die vollständige Demo-Code ist in C++ geschrieben und basiert auf dem Microsofts SEAL und PASTA-Bibliothek. Zunächst erstellen wir 2 Strukturen, die den Client und den Server darstellen:
struct Client
{
// the HE keys
seal::PublicKey he_pk; // HE public key
seal::SecretKey he_sk; // HE secret key
seal::RelinKeys he_rk; // HE relinearization key (you don't have to care about this)
seal::GaloisKeys he_gk; // HE galois key (you don't have to care about this)
// client's symmetric keys
std::vector<uint64_t> k; // the secret symmetric keys
std::vector<seal::Ciphertext> c_k; // the HE encrypted symmetric keys
// client's data
std::vector<uint64_t> m{0, 5, 255, 100, 255}; // the client's secret data
std::vector<uint64_t> c_s; // the symmetric encrypted data
seal::Ciphertext c_res; // the HE encrypted result received from the server
};
struct Server
{
std::vector<int64_t> w{-1, 2, -3, 4, 5}; // dummy weights
std::vector<int64_t> b{-5, -5, -5, -5, -5}; // dummy biases
std::vector<seal::Ciphertext> c; // the HE encrypted ciphertext of client's data
seal::SecretKey he_sk; // the server's HE secret key
seal::Ciphertext c_res; // the HE encrypted results that will be sent to the client
};
Client client;
Server server;
Schritt 1
Der Client erstellt den SEAL-Kontext, der für die Erstellung der HE-Schlüssel und anderer SEAL-Objekte für die Verschlüsselung und Entschlüsselung der Daten zuständig ist (BatchEncoder, Encryptor, Decryptor, Evaluator).
std::shared_ptr<seal::SEALContext> context = sealhelper::get_seal_context();
sealhelper::print_parameters(*context);
seal::KeyGenerator keygen(*context);
keygen.create_public_key(client.he_pk);
client.he_sk = keygen.secret_key();
keygen.create_relin_keys(client.he_rk);
seal::BatchEncoder he_benc(*context);
seal::Encryptor he_enc(*context, client.he_pk);
seal::Evaluator he_eval(*context);
seal::Decryptor he_dec(*context, client.he_sk);
bool use_bsgs = false;
std::vector<int> gk_indices = pastahelper::add_gk_indices(use_bsgs, he_benc);
keygen.create_galois_keys(gk_indices, client.he_gk);
Der Client führt dann den Verschlüsselungsalgorithmus(HHE.Enc) aus, um den symmetrischen Schlüssel(client.k) und den symmetrischen Chiffretext(client.c_s) zu erstellen.
client.k = pastahelper::get_symmetric_key();
pasta::PASTA SymmetricEncryptor(client.k, configs::plain_mod);
client.c_s = SymmetricEncryptor.encrypt(client.m);
Wenn wir die Werte von client.c_s sehen wir einen Vektor mit Zufallswerten wie [30446, 62410, 62969, 38863, 43376], im Gegensatz zu den Klartextdaten des Clients [0, 5, 255, 100, 255]. Der Client sendet nur den Vektor der Zufallswerte an den Server, aber niemals seine Klartextdaten.
Als nächstes verschlüsselt der Kunde seinen symmetrischen Schlüssel(client.k) mit HE, um client.c_k zu erstellen.
client.c_k = pastahelper::encrypt_symmetric_key(client.k,
configs::USE_BATCH,
he_benc,
he_enc);
Danach sendet der Client client.c_k, client.c_s und die HE-Schlüssel mit Ausnahme des geheimen Schlüssels an den Server.
Schritt 2
Nach Erhalt der client.c_k erstellt der Server seinen eigenen geheimen HE-Schlüssel, das HHE-Objekt, und führt den Dekompositionsalgorithmus durch, der folgende Ergebnisse liefert server.c das ist der HE-Chiffretext der Klartextnachricht des Clients m. Beachten Sie, dass der Client niemals seinen geheimen Schlüssel sendet er_sk an den Server, so dass der Server nicht in der Lage sein wird, die server.c.
seal::KeyGenerator csp_keygen(*context);
server.he_sk = csp_keygen.secret_key();
pasta::PASTA_SEAL HHE(context, client.he_pk, server.he_sk, client.he_rk, client.he_gk);
server.c = HHE.decomposition(client.c_s, client.c_k, configs::USE_BATCH);
Der Server verschlüsselt dann seine Gewichte w und Vorzeichen b und führt eine elementweise Vektormultiplikation sowie eine Addition seiner Klartextgewichte und Vorzeichen mit den HE-verschlüsselten Daten server.c durch.
seal::Plaintext plain_w, plain_b;
he_benc.encode(server.w, plain_w);
he_benc.encode(server.b, plain_b);
server.c_res = sealhelper::he_mult(he_eval, server.c[0], plain_w);
client.c_res = sealhelper::he_add(he_eval, server.c_res, plain_b);
Das Endergebnis ist client.c_res, also der SEAL-Chiffretext, den der Client erhält.
Schritt 3
Schließlich entschlüsselt der Kunde seine c_res mit seinem geheimen Schlüssel:
std::vector<int64_t> decrypted_res = sealhelper::decrypt(client.c_res,
client.he_sk,
he_benc,
*context,
client.m.size());
Wenn wir decrypted_res ausdrucken, sehen wir, dass das Ergebnis [-5 5 -770 395 1270] lautet, was korrekt ist, weil
[0, 5, 255, 100, 255]
⊙
[-1, 2, -3, 4, 5]
⊕
[-5, -5, -5, -5, -5]
=
[-5, 5, -770, 395, 1270]
wobei ⊙ und ⊕ die elementweise Multiplikation bzw. Addition der Vektoren bedeuten.
Das Ergebnis der Ausführung des Beispielcodes ist in der folgenden Abbildung zu sehen
Zukünftige Richtungen und Schlussfolgerungen
In diesem Artikel lernten wir etwas über hybride homomorphe Verschlüsselung, ihre Vorteile gegenüber einfacher homomorpher Verschlüsselung, einen beispielhaften Anwendungsfall von HHE und gingen auch durch ein sehr einfaches Demonstrationsprotokoll in C++. In der Praxis kann dieses Protokoll auf 3 Parteien erweitert werden, was für die verschlüsselte Datenanalyse oder das maschinelle Lernen geeignet ist. Weitere Informationen über das 3-Parteien-HHE-Protokoll finden Sie in einem kürzlich veröffentlichten Papier [3] auf unserer NISEC-Labor an der Universität Tampere. Ich hoffe, Sie finden diesen Artikel nützlich und haben Spaß daran, in der Zwischenzeit etwas Neues zu lernen!
Danksagung
Diese Arbeit wurde durch das EU-Projekt HARPOCRATES finanziert.
Referenz
[1] Brakerski, Zvika, und Vinod Vaikuntanathan. “Effiziente vollständig homomorphe Verschlüsselung aus (Standard-)LWE”. SIAM Journal on computing 43.2 (2014): 831-871.
[2] Dobraunig, Christoph, et al. “Pasta: ein Fall für hybride homomorphe Verschlüsselung”. Kryptologie ePrint Archiv (2021).
[3] Alexandros Bakas, Eugene Frimpong, Antonis Michalas. “Symmetrische Verschleierung: Realisierung homomorpher Verschlüsselungsdienste aus symmetrischen Primitiven”. EAI SECURECOMM (2022).
Geschrieben von: Khoa Nguyen, Universität Tampere