Security & Privacy
GDPR-konforme Android-App mit End-to-End-Verschlüsselung
51 min
wie man eine gdpr konforme chat app erstellt einführung ahoy back4app community! dies ist ein gast tutorial vom team bei virgil security, inc https //virgilsecurity com/?utm source=back4app\&utm medium=blog\&utm campaign=e2eechat wir sind die krypto technologie hinter twilios ende zu ende verschlüsselte nachrichten https //www twilio com/blog/2016/05/introducing end to end encryption for twilio ip messaging with virgil security html unsere freunde @ back4app haben uns gebeten, ihnen zu zeigen, wie man eine ende zu ende verschlüsselte chat app auf back4app aufbaut in diesem beitrag führen wir sie durch die schritte, um eine einfache back4app android messenger app ende zu ende verschlüsselt zu machen! sind sie bereit? ps wenn ihnen die details egal sind, überspringen sie einfach das ende des beitrags und laden sie das endprodukt herunter was ist ende zu ende verschlüsselung? zuerst lassen sie uns mit einer kurzen auffrischung beginnen, was e2ee (ende zu ende verschlüsselung) ist und wie es funktioniert e2ee ist einfach wenn sie eine chat nachricht eingeben, wird sie auf ihrem mobilen gerät (oder in ihrem browser) verschlüsselt und erst entschlüsselt, wenn ihr chat partner sie erhält und sie im chatfenster anzeigen möchte die nachricht bleibt verschlüsselt, während sie über wlan und das internet, durch die cloud / den webserver, in eine datenbank und auf dem rückweg zu ihrem chat partner reist mit anderen worten, keine der netzwerke oder server hat eine ahnung, worüber sie beide chatten was bei der ende zu ende verschlüsselung schwierig ist, ist die aufgabe, die verschlüsselungsschlüssel so zu verwalten, dass nur die an dem chat beteiligten benutzer darauf zugreifen können und niemand sonst und wenn ich „niemand sonst“ schreibe, meine ich das wirklich selbst insider ihres cloud anbieters oder sogar sie, der entwickler, sind ausgeschlossen; keine versehentlichen fehler https //techcrunch com/2017/11/29/meet the man who deactivated trumps twitter account/ oder rechtlich erzwungenes spähen sind möglich krypto zu schreiben, insbesondere für mehrere plattformen, ist schwierig echte zufallszahlen zu generieren, die richtigen algorithmen auszuwählen und die richtigen verschlüsselungsmodi zu wählen, sind nur einige beispiele, die die meisten entwickler dazu bringen, die hände in die luft zu werfen und es letztendlich einfach nicht zu tun dieser blogbeitrag zeigt ihnen, wie sie all diese lästigen details ignorieren und schnell und einfach end to end verschlüsselung mit virgils sdk durchführen können für eine einführung, so werden wir die messenger app von back4app auf end to end verschlüsselung aufrüsten während der anmeldung wir generieren die individuellen privaten und öffentlichen schlüssel für neue benutzer (denken sie daran der öffentliche schlüssel des empfängers verschlüsselt nachrichten und der passende private schlüssel des empfängers entschlüsselt sie) vor dem senden von nachrichten verschlüsseln sie die chatnachrichten mit dem öffentlichen schlüssel des empfängers nach dem empfang von nachrichten entschlüsseln sie die chatnachrichten mit dem privaten schlüssel des empfängers wir werden die öffentlichen schlüssel der benutzer im virgils kartenservice veröffentlichen, damit die chatbenutzer einander nachschlagen und nachrichten füreinander verschlüsseln können die privaten schlüssel bleiben auf den benutzergeräten halten sie es einfach dies ist die einfachste mögliche implementierung von e2ee chat und sie funktioniert perfekt für einfache chat apps zwischen 2 benutzern, wo gespräche kurzlebig sind und es in ordnung ist, die nachrichtenhistorie zu verlieren, wenn ein gerät mit dem privaten schlüssel darauf verloren geht ok, genug geredet! lass uns mit dem programmieren beginnen wir beginnen damit, dich durch die einrichtung der android app zu führen, dann fügen wir etwas code hinzu, um die app ende zu ende verschlüsselt zu machen voraussetzungen um dieses tutorial abzuschließen, benötigst du android studio eine app, die bei back4app erstellt wurde folge dem tutorial "neue app erstellen" um zu lernen, wie man eine app bei back4app erstellt melde dich für ein virgil security konto an (wir werden die app später erstellen) lass uns die „saubere“ back4app messenger app einrichten 1 richte deinen app server ein lass uns mit der bereitstellung der cloud funktion beginnen dazu musst du finde main js main js und package json package json im scripts scripts verzeichnis; öffne main js main js mit deinem bevorzugten editor 1 1) hol dir die back4app anmeldeinformationen öffne dashboard dashboard deiner app > app einstellungen app einstellungen > sicherheit & schlüssel sicherheit & schlüssel in main js main js , ersetzen sie parse app id parse app id mit ihrer anwendungs id anwendungs id und parse rest api key parse rest api key mit ihrem rest api schlüssel rest api schlüssel 1 2) holen sie sich virgil anmeldeinformationen erstellen sie eine anwendung bei virgil dashboard https //dashboard virgilsecurity com/ öffnen sie ihre neue virgil anwendung, navigieren sie zum e3kit bereich und generieren sie eine env env datei im e3kit bereich in der linken seitenleiste kopieren sie die werte von app id app id , app key app key , und app key id app key id aus der env env datei ersetzen sie die kopierten werte in ihrer main js main js datei in den entsprechenden feldern ( main js main js von scripts scripts verzeichnis) 1 3) cloud code funktion bereitstellen öffnen sie das back4app “dashboard” ihrer app > “core” > cloud code funktionen; klicken sie auf +hinzufügen und wählen sie ihre main js und package json (aus dem skripte verzeichnis) aus, danach verschieben sie beide in den cloud ordner; klicken sie auf deploy 2 starten sie die saubere back4app kotlin demo app vergessen sie nicht, zuerst die back4app cloud code funktion einzurichten es ist ein obligatorischer teil dieser demo gehen sie danach die folgenden schritte durch 2 1) projekt in android studio importieren öffnen sie android studio > datei datei > neu neu > projekt aus versionskontrolle projekt aus versionskontrolle > git git git repository url https //github com/virgilsecurity/chat back4app android überprüfen sie den clean chat kt clean chat kt branch wichtig! wählen sie den dateibaumtyp „projekt“ er wird während des gesamten tutorials verwendet 2 2) back4app anmeldeinformationen im projekt einrichten öffnen sie das back4app „dashboard“ ihrer app > „app einstellungen“ > „sicherheit & schlüssel“; gehe zu /app/src/main/res/values/strings xml /app/src/main/res/values/strings xml datei in deinem android projekt und ersetze your back4app app id your back4app app id mit deiner anwendungs id anwendungs id und your back4app client key your back4app client key mit deinem client schlüssel client schlüssel 2 3) db einrichten öffne back4app “dashboard” > “core” > “datenbank browser” > “eine klasse erstellen” und erstelle klassen vom benutzerdefinierten benutzerdefinierten typ mit dem namen nachricht nachricht und chatthread chatthread ; 2 4) live abfrage einrichten gehe zurück zu deinem back4app konto https //dashboard back4app com/apps/#!/admin drücke den servereinstellungen servereinstellungen button in deiner anwendung finde den block „webhosting und live abfrage“ öffne die live abfrage einstellungen und überprüfe die hosting aktivieren hosting aktivieren option wähle einen namen für deine subdomain, um die live abfrage für die 2 klassen zu aktivieren, die du erstellt hast nachricht nachricht und chatthread chatthread kopiere deinen neuen subdomain namen und klicke auf die schaltfläche speichern gehe zurück zu /app/src/main/res/values/strings xml /app/src/main/res/values/strings xml und füge den „subdomain namen“, den du oben eingegeben hast, in die back4app live query url back4app live query url anstelle von „yoursubdomainname“ ein nach diesen schritten sollten sie in der lage sein, die schaltfläche ausführen in android studio zu drücken und das beispiel zum laufen zu bringen verwenden sie den emulator oder ein echtes gerät, um es auszuprobieren 3 führen sie die saubere demo aus um das ergebnis der ausführung der sauberen version der demo zu sehen, müssen sie 2 benutzer anmelden; eine unterhaltung zwischen ihnen starten und ein paar nachrichten senden; 3\ öffnen sie das back4app „dashboard“ > „core“ > „datenbank browser“ > „nachricht“ wenn alles funktioniert hat, sollten sie die chat messenger app sehen, die erscheint registrieren sie zwei benutzer und senden sie ein paar nachrichten aneinander sie sollten neue daten in der sehen nachricht nachricht klasse bitte beachten sie, dass sie auf dem server sehen können, worüber ihre benutzer chatten nächster schließen sie ihre chat oberfläche und fahren sie mit dem nächsten schritt fort – das hinzufügen von e2ee verschlüsselung jetzt lassen sie uns diese nachrichten end to end verschlüsseln! am ende dieses teils werden ihre chat nachrichten auf dem server so aussehen können sie den unterschied erkennen? wie kommen wir dorthin? offensichtlich müssen wir die end to end verschlüsselung implementieren, was bedeutet, dass unsere app das private und öffentliche schlüsselpaar im rahmen der anmeldung generieren den privaten schlüssel im schlüsselspeicher auf dem gerät des benutzers speichern den öffentlichen schlüssel im virgil’s card service als „virgil card“ veröffentlichen, damit andere benutzer ihn herunterladen und nachrichten damit verschlüsseln können nachrichten mit dem öffentlichen schlüssel verschlüsseln und mit dem privaten schlüssel signieren; nachrichten mit dem privaten schlüssel entschlüsseln und mit dem öffentlichen schlüssel verifizieren dafür müssen wir e3kit zu unserer sauberen demoversion hinzufügen und etwas mehr code implementieren, um alles, was oben beschrieben wurde, umzusetzen aber bevor wir beginnen, lassen sie uns zwei wichtige begriffe klären was ist eine virgil card und ein privater schlüssel? virgil card virgil cards tragen die privaten schlüssel der benutzer virgil cards werden im virgil’s cards service veröffentlicht (stellen sie sich diesen service wie ein telefonbuch vor), damit andere benutzer sie abrufen können alice muss bobs öffentlichen schlüssel abrufen, um eine nachricht für bob mit diesem schlüssel zu verschlüsseln privater schlüssel ein privater teil des verschlüsselungsschlüssels denken sie daran, dass private schlüssel daten entschlüsseln können, die mit dem passenden öffentlichen schlüssel verschlüsselt wurden 1 fügen sie e3kit zur sauberen e3kit back4app kotlin demo hinzu fügen sie im app level ( modul app modul app ) gradle bei /app/build gradle /app/build gradle hinzu (aber synchronisieren sie die gradle skripte noch nicht) fügen sie folgendes am ende ihrer projektebene hinzu /build gradle /build gradle ( projekt chat back4app android projekt chat back4app android ) jetzt können sie die gradle skripte synchronisieren; aktualisieren sie ihre appvirgil appvirgil klasse, indem sie neue felder hinzufügen drücken sie alt+ enter alt+ enter um die erforderlichen bibliotheken in die klasse zu importieren 2 authentifizieren sie benutzer mit back4app cloud code im /virgilsecurity/virgilback4app/model/ /virgilsecurity/virgilback4app/model/ verzeichnis erstellen sie datenklassen authenticateresponse authenticateresponse und virgiljwtresponse virgiljwtresponse die antworten von cloud code funktionen darstellen im /virgilsecurity/virgilback4app/util/ /virgilsecurity/virgilback4app/util/ erstellen sie authrx authrx objekt, das aufrufe an cloud code funktionen implementiert (vergessen sie nicht, danach alle erforderlichen bibliotheken zu importieren) 1 object authrx { 2 3 / 4 you can call it only after successful \[authenticate] 5 / 6 fun virgiljwt(sessiontoken string) = single create\<string> { emitter > 7 val requestparams = mutablemapof\<string, string>() apply { 8 put("sessiontoken", sessiontoken) 9 } 10 11 parsecloud callfunctioninbackground\<map\<string, any>>( 12 key virgil jwt, 13 requestparams 14 ) { virgiljwt, exception > 15 if (exception == null) 16 emitter onsuccess(virgiljwt\[key token] tostring()) 17 else 18 emitter onerror(exception) 19 20 } 21 } 22 23 private const val key virgil jwt = "virgil jwt" 24 private const val key token = "token" 25 } 3 speichern sie das virgil jwt lokal das von cloud code funktionen empfangene virgil token muss lokal gespeichert werden lassen sie uns die einstellungen einstellungen klasse in /virgilsecurity/virgilback4app/util/ /virgilsecurity/virgilback4app/util/ konstante definieren fügen sie funktionen hinzu setvirgiltoken setvirgiltoken , virgiltoken virgiltoken und clearvirgiltoken clearvirgiltoken kotlin fun setvirgiltoken(virgiltoken string) { with(sharedpreferences edit()) { putstring(key virgil token, virgiltoken) apply() } } fun virgiltoken() string? { with(sharedpreferences) { return getstring(key virgil token, null) } } fun clearvirgiltoken() { with(sharedpreferences edit()) { remove(key virgil token) apply() } } 1 virgil token should be reset on logout let's add `preferences instance(this) clearvirgiltoken()` line into `initdrawer` function of `threadslistactivity` class (in ` /virgilsecurity/virgilback4app/chat/contactslist/`) 2 kotlin 3 private fun initdrawer() { 4 5 nvnavigation setnavigationitemselectedlistener { item > 6 r id itemlogout > { 7 dldrawer closedrawer(gravitycompat start) 8 presenter disposeall() 9 showbaseloading(true) 10 // new code >> 11 preferences instance(this) clearvirgiltoken() 12 // << new code 13 14 } 15 } 16 } 4 benutzerregistrierung ändern e3kit kümmert sich um ihre privaten und öffentlichen schlüssel um sie während des registrierungsprozesses zu generieren, müssen wir folgendes tun in /virgilsecurity/virgilback4app/util/ /virgilsecurity/virgilback4app/util/ erstellen sie die rxethree rxethree klasse jetzt füge initethree initethree funktion hinzu, die die e3kit instanz in der rxethree rxethree klasse initialisiert 1 import com virgilsecurity android common model ethreeparams 2 import com virgilsecurity android ethree interaction ethree 3 4 5 fun initethree(identity string, verifyprivatekey boolean = false) 6single\<ethree> = single create { e > 6 val params = ethreeparams(identity, {preferences virgiltoken()!!}, context) 7 val ethree = ethree(params) 8 if (verifyprivatekey) { 9 if (ethree haslocalprivatekey()) { 10 e onsuccess(ethree) 11 } else { 12 e onerror(keyentrynotfoundexception()) 13 } 14 } else { 15 e onsuccess(ethree) 16 } 17 } fügen sie registerethree registerethree funktion hinzu, die einen neuen benutzer zur rxethree rxethree klasse registriert e3kit generiert ein schlüsselpaar während der anmeldung der generierte private schlüssel wird dann im lokalen speicher gespeichert, und der öffentliche schlüssel wird als virgil karte an die virgil dienste veröffentlicht 1 import com android virgilsecurity virgilback4app appvirgil 2 import com virgilsecurity common callback oncompletelistener 3 import io reactivex completable 4 5 6 fun registerethree() completable = completable create { e > 7 appvirgil ethree register() addcallback(object oncompletelistener { 8 override fun onerror(throwable throwable) { 9 e onerror(throwable) 10 } 11 12 override fun onsuccess() { 13 e oncomplete() 14 } 15 16 }) 17 } lass uns einige updates an der loginpresenter loginpresenter klasse (in /virgilsecurity/virgilback4app/auth/) /virgilsecurity/virgilback4app/auth/) füge das rxethree rxethree feld hinzu 1 private val rxethree = rxethree(context) aktualisiere die requestsignup requestsignup funktion, um die registrierung mit e3kit durchzuführen jetzt lass uns änderungen an der requestsignin requestsignin methode der loginpresenter loginpresenter klasse (in /virgilsecurity/virgilback4app/auth/) /virgilsecurity/virgilback4app/auth/) 1 fun requestsignin(identity string, 2 onsuccess () > unit, 3 onerror (throwable) > unit) { 4 5 val password = generatepassword(identity tobytearray()) 6 7 val disposable = rxparse login(identity, password) 8 subscribeon(schedulers io()) 9 observeon(schedulers io()) 10 // new code >> 11 flatmap { authrx virgiljwt(it sessiontoken) } 12 map { preferences setvirgiltoken(it) } 13 flatmap { rxethree initethree(identity, true) } 14 map { appvirgil ethree = it } 15 // << new code 16 observeon(androidschedulers mainthread()) 17 // updated code >> 18 subscribeby( 19 onsuccess = { 20 onsuccess() 21 }, 22 onerror = { 23 onerror(it) 24 } 25 ) 26 // << updated code 27 28 compositedisposable += disposable 29 } 6 holen sie sich die liste der vorhandenen chats als nächstes fügen sie funktionen hinzu, die die e3kit initialisierung in die threadslistfragment threadslistfragment klasse (in /virgilsecurity/virgilback4app/chat/contactslist/) /virgilsecurity/virgilback4app/chat/contactslist/) 1 private fun oninitethreesuccess() { 2 presenter requestthreads(parseuser getcurrentuser(), 3 20, 4 page, 5 const tablenames created at criteria, 6 ongetthreadssuccess, 7 ongetthreadserror) 8 } 9 10 private fun oninitethreeerror(throwable throwable) { 11 showprogress(false) 12 if (adapter itemcount == 0) 13 tverror visibility = view\ visible 14 15 utils toast(activity, utils resolveerror(throwable)) 16 } aktualisieren sie postcreateinit postcreateinit funktion zur initialisierung von e3kit 1 override fun postcreateinit() { 2 3 presenter = threadslistfragmentpresenter(activity) 4 5 showprogress(true) 6 // updated code >> 7 if (appvirgil isethreeinitialized()) { 8 presenter requestthreads(parseuser getcurrentuser(), 9 20, 10 page, 11 const tablenames created at criteria, 12 ongetthreadssuccess, 13 ongetthreadserror) 14 } else { 15 presenter requestethreeinit(parseuser getcurrentuser(), oninitethreesuccess, oninitethreeerror) 16 } 17 // << updated code 18 } und fügen sie den folgenden code in die threadslistfragmentpresenter threadslistfragmentpresenter klasse in virgilsecurity virgilback4app chat contactslist/ virgilsecurity virgilback4app chat contactslist/ feld hinzufügen 1 private val rxethree = rxethree(context) und funktion 1 fun requestethreeinit(currentuser parseuser, onsuccess () > unit, onerror (throwable) > unit) { 2 val disposable = rxethree initethree(currentuser username) 3 subscribeon(schedulers io()) 4 observeon(androidschedulers mainthread()) 5 subscribeby( 6 onsuccess = { 7 appvirgil ethree = it 8 onsuccess() 9 }, 10 onerror = { 11 onerror(it) 12 } 13 ) 14 15 compositedisposable += disposable 16 } an diesem punkt sind wir in der lage, einen benutzer zu registrieren/anzumelden und einen neuen chat mit einem anderen benutzer zu erstellen jetzt fügen wir die verschlüsselung für unsere nachrichten hinzu 7 nachrichtenverschlüsselung und entschlüsselung lassen sie uns die findcard findcard funktion zur rxethree rxethree klasse hinzufügen (in /virgilsecurity/virgilback4app/util/ /virgilsecurity/virgilback4app/util/ ) die uns hilft, die neueste virgil karte anhand des benutzernamens zu erhalten 1 fun findcard(identity string) single\<card> = single create { e > 2 appvirgil ethree finduser(identity) addcallback(object onresultlistener\<card> { 3 override fun onerror(throwable throwable) { 4 e onerror(throwable) 5 } 6 7 override fun onsuccess(result card) { 8 e onsuccess(result) 9 } 10 11 }) 12 } wenn ein chat geöffnet wird, sollten wir die virgil karte des empfängers erhalten bearbeiten postcreateinit postcreateinit von chatthreadfragment chatthreadfragment klasse (in /virgilsecurity/virgilback4app/chat/thread/ /virgilsecurity/virgilback4app/chat/thread/ ) indem wir ersetzen 1 presenter requestmessages(thread, 2 50, 3 page, 4 const tablenames created at criteria, 5 ongetmessagessuccess, 6 ongetmessageserror) code mit einem neuen ersetzen 1 presenter requestcard(recipientid, 2 ongetcardsuccess, 3 ongetcarderror) und füge zwei funktionen hinzu 1 private fun ongetcardsuccess(card card) { 2 showprogress(false) 3 adapter interlocutorcard = card 4 presenter requestmessages(thread, 5 50, 6 page, 7 const tablenames created at criteria, 8 ongetmessagessuccess, 9 ongetmessageserror) 10 } 11 12 private fun ongetcarderror(t throwable) { 13 if (t is virgilcardisnotfoundexception || t is virgilcardserviceexception) { 14 utils toast(this, 15 "virgil card is not found \nyou can not chat with user without virgil card") 16 activity onbackpressed() 17 } 18 showprogress(false) 19 srlrefresh isrefreshing = false 20 locksendui(lock = false, lockinput = false) 21 22 utils toast(this, utils resolveerror(t)) 23 } jetzt lass uns chatthreadpresenter chatthreadpresenter felder hinzufügen 1 private val ethree = appvirgil ethree 2 private lateinit var usercard card 3 private val rxethree = rxethree(context) fügen sie eine funktion hinzu, die eine virgil karte des empfängers abruft 1 fun requestcard(identity string, 2 onsuccess (card) > unit, 3 onerror (throwable) > unit) { 4 5 val disposable = rxethree findcard(identity) 6 subscribeon(schedulers io()) 7 observeon(androidschedulers mainthread()) 8 subscribeby( 9 onsuccess = { 10 usercard = it 11 onsuccess(it) 12 }, 13 onerror = { 14 onerror(it) 15 } 16 ) 17 18 compositedisposable += disposable 19 } fügen sie die verschlüsselung der ausgehenden nachrichten in requestsendmessage requestsendmessage funktion hinzu 1 fun requestsendmessage(text string, 2 thread chatthread, 3 onsuccess () > unit, 4 onerror (throwable) > unit) { 5 6 val encryptedtext = ethree authencrypt(text, usercard) 7 val disposable = rxparse sendmessage(encryptedtext, thread) 8 9 } fügen sie die entschlüsselung aller eingehenden nachrichten in die chatthreadrvadapter chatthreadrvadapter klasse ein (in /virgilsecurity/virgilback4app/chat/thread/) /virgilsecurity/virgilback4app/chat/thread/) felder hinzufügen 1 private var ethree ethree = appvirgil ethree 2 lateinit var interlocutorcard card implementiere die nachrichtenentschlüsselung in onbindviewholder onbindviewholder funktion 1 override fun onbindviewholder(viewholder recyclerview\ viewholder, position int) { 2 when (viewholder) { 3 is holdermessageme > { 4 val decryptedtext = ethree authdecrypt(items\[position] body) 5 viewholder bind(decryptedtext) 6 } 7 is holdermessageyou > { 8 val decryptedtext = ethree authdecrypt(items\[position] body, interlocutorcard) 9 viewholder bind(decryptedtext) 10 } 11 } 12 } 8 führen sie die vollständige end to end verschlüsselte demo aus um das ergebnis unserer vollständig ende zu ende verschlüsselten demo zu sehen, gehen sie diese schritte erneut durch melden sie den vorherigen benutzer ab registrieren sie 2 neue benutzer; starten sie eine konversation zwischen ihnen und senden sie ein paar nachrichten; öffnen sie back4app „dashboard“ > „core“ > „datenbankbrowser“ > „nachricht“ wichtig! sie müssen den aktuellen benutzer abmelden und zwei neue benutzer registrieren, danach können sie mit diesen beiden neuen benutzern einen e2ee chat starten der grund ist, dass ihre ersten beiden benutzer keine virgil card virgil card haben, sodass sie die verschlüsselung\entschlüsselung für sie nicht verwenden können { blockquote tip} fertig! jetzt können sie sehen, dass die nachrichten der benutzer verschlüsselt sind und nur von den benutzern selbst in der app abgerufen werden können hipaa & gdpr konformität ende zu ende verschlüsselung ist eine möglichkeit, die technischen anforderungen für hipaa (das us amerikanische gesetz über die portabilität und rechenschaftspflicht von krankenversicherungen von 1996) und gdpr (die datenschutz grundverordnung der europäischen union) zu erfüllen wenn sie weitere details benötigen, registrieren sie sich für ein kostenloses virgil konto https //developer virgilsecurity com/account/signup?utm source=back4app\&utm medium=blog\&utm campaign=e2eechat , treten sie unserer slack community bei und kontaktieren sie uns dort wir freuen uns, ihre eigenen datenschutzumstände zu besprechen und ihnen zu helfen, zu verstehen, was erforderlich ist, um die technischen anforderungen von hipaa und gdpr zu erfüllen was kommt als nächstes? abschlussprojekt https //github com/virgilsecurity/chat back4app android/ wenn sie teile des puzzles verpasst haben, öffnen sie den e2ee projektzweig sie können ihre anwendungsanmeldeinformationen in diesen code einfügen (wie sie es während des artikels getan haben) und das projekt erstellen sie finden weitere informationen darüber, was sie mit virgil security hier https //virgilsecurity com/?utm source=back4app\&utm medium=blog\&utm campaign=e2eechat