Construcción de app chat con cifrado E2EE y cumplimiento GDPR
53 min
cómo hacer una aplicación de chat compatible con el gdpr introducción ¡hola comunidad de back4app! este es un tutorial de invitado del equipo de virgil security, inc https //virgilsecurity com/?utm source=back4app\&utm medium=blog\&utm campaign=e2eechat somos la tecnología criptográfica detrás de la mensajería cifrada de extremo a extremo de twilio https //www twilio com/blog/2016/05/introducing end to end encryption for twilio ip messaging with virgil security html nuestros amigos de back4app nos pidieron que te mostremos cómo construir una aplicación de chat cifrada de extremo a extremo sobre back4app en esta publicación, te guiaremos a través de los pasos para hacer que una simple aplicación de mensajería de back4app para android sea cifrada de extremo a extremo ¿estás listo? pd si no te importan los detalles, simplemente salta al final de la publicación y descarga el producto final ¿qué es el cifrado de extremo a extremo? primero, comencemos con un rápido repaso de qué es e2ee (cifrado de extremo a extremo) y cómo funciona e2ee es simple cuando escribes un mensaje de chat, se cifra en tu dispositivo móvil (o en tu navegador) y se descifra solo cuando tu compañero de chat lo recibe y quiere mostrarlo en la ventana de chat el mensaje permanece cifrado mientras viaja por wi fi e internet, a través de la nube / servidor web, en una base de datos, y de regreso a tu compañero de chat en otras palabras, ninguna de las redes o servidores tiene idea de lo que ustedes dos están chateando lo que es difícil en el cifrado de extremo a extremo es la tarea de gestionar las claves de cifrado de manera que solo los usuarios involucrados en el chat puedan acceder a ellas y nadie más y cuando escribo “nadie más”, lo digo en serio incluso los empleados de tu proveedor de nube o incluso tú, el desarrollador, quedan fuera; no se permiten errores accidentales https //techcrunch com/2017/11/29/meet the man who deactivated trumps twitter account/ o miradas forzadas legalmente escribir criptografía, especialmente para múltiples plataformas, es difícil generar números verdaderamente aleatorios, elegir los algoritmos correctos y seleccionar los modos de cifrado adecuados son solo algunos ejemplos que hacen que la mayoría de los desarrolladores levanten las manos al aire y terminen simplemente no haciéndolo esta publicación de blog te mostrará cómo ignorar todos estos detalles molestos y encriptar de extremo a extremo de manera rápida y sencilla utilizando el sdk de virgil para una introducción, así es como actualizaremos la aplicación de mensajería de back4app para que sea encriptada de extremo a extremo durante el registro generaremos las claves privadas y públicas individuales para los nuevos usuarios (recuerda la clave pública del destinatario encripta los mensajes y la clave privada correspondiente del destinatario los desencripta) antes de enviar mensajes, encriptarás los mensajes de chat con la clave pública del destinatario después de recibir mensajes, desencriptarás los mensajes de chat con la clave privada del destinatario publicaremos las claves públicas de los usuarios en el servicio de tarjetas de virgil para que los usuarios de chat puedan buscarse entre sí y encriptar mensajes el uno para el otro las claves privadas permanecerán en los dispositivos de los usuarios mantenlo simple esta es la implementación más simple posible de un chat e2ee y funciona perfectamente para aplicaciones de chat simples entre 2 usuarios donde las conversaciones son efímeras y está bien perder el historial de mensajes si se pierde un dispositivo con la clave privada en él ¡está bien, suficiente charla! vamos a ponernos a codificar comenzaremos guiándote a través de la configuración de la aplicación de android, luego, agregaremos algo de código para hacer que la aplicación sea cifrada de extremo a extremo requisitos previos para completar este tutorial, necesitas android studio una aplicación creada en back4app sigue el tutorial crear nueva aplicación https //www back4app com/docs/get started/new parse app para aprender cómo crear una aplicación en back4app regístrate para una cuenta de virgil security https //developer virgilsecurity com/account/signup?utm source=back4app\&utm medium=blog\&utm campaign=e2eechat (crearemos la aplicación más tarde) configuramos la aplicación de mensajería “limpia” de back4app 1 configura tu servidor de aplicaciones comencemos con el despliegue de la función en la nube para esto, necesitarás encontrar \<font color="#2166ae">main js\</font> y \<font color="#2166ae">package json\</font> en el directorio \<font color="#2166ae">scripts\</font> ; abre \<font color="#2166ae">main js\</font> con tu editor favorito 1 1) obtén las credenciales de back4app abre \<font color="#2166ae">dashboard\</font> de tu aplicación > \<font color="#2166ae">configuración de la aplicación\</font> > \<font color="#2166ae">seguridad y claves\</font> en \<font color="#2166ae">main js\</font> , reemplaza \<font color="#2166ae">parse app id\</font> con tu \<font color="#2166ae">id de aplicación\</font> y \<font color="#2166ae">parse rest api key\</font> con tu \<font color="#2166ae">clave api rest\</font> 1 const parse app id = "your parse app id" ; 2 const parse rest api key = "your parse rest api key" ; 1 2) obtén credenciales de virgil crea una aplicación en virgil dashboard https //dashboard virgilsecurity com/ abre tu nueva aplicación virgil, navega a la sección e3kit y genera un \<font color="#2166ae"> env\</font> archivo en la sección e3kit en la barra lateral izquierda copia los valores de \<font color="#2166ae">app id\</font> , \<font color="#2166ae">app key\</font> , y \<font color="#2166ae">app key id\</font> del archivo \<font color="#2166ae"> env\</font> reemplace los valores copiados en su \<font color="#2166ae">main js\</font> archivo en los campos correspondientes ( \<font color="#2166ae">main js\</font> de \<font color="#2166ae">scripts\</font> directorio) 1 const app id = "your virgil app id" ; 2 const app key = "your virgil app key" ; 3 const app key id = "your virgil app id" ; 1 3) desplegar función de código en la nube abra el “tablero” de back4app de su aplicación > “núcleo” > funciones de código en la nube; haz clic en +agregar y selecciona tu main js y package json (del directorio de scripts), después mueve ambos a la carpeta de la nube; haz clic en desplegar 2 iniciar la aplicación de demostración de back4app kotlin limpia no olvides configurar primero la función de código en la nube de back4app es una parte obligatoria de esta demostración después de esto, sigue los siguientes pasos 2 1) importar proyecto en android studio abre android studio > \<font color="#2166ae">archivo\</font> > \<font color="#2166ae">nuevo\</font> > \<font color="#2166ae">proyecto desde control de versiones\</font> > \<font color="#2166ae">git\</font> url del repositorio de git https //github com/virgilsecurity/chat back4app android revisa la \<font color="#2166ae">clean chat kt\</font> rama ¡importante! selecciona el tipo de árbol de archivos “proyecto” se utilizará a lo largo de todo el tutorial 2 2) configurar las credenciales de back4app en el proyecto abre el “tablero” de back4app de tu aplicación > “configuraciones de la aplicación” > “seguridad y claves”; ve al \<font color="#2166ae">/app/src/main/res/values/strings xml\</font> archivo en tu proyecto de android y reemplaza \<font color="#2166ae">your back4app app id\</font> con tu \<font color="#2166ae">id de aplicación\</font> y \<font color="#2166ae">your back4app client key\</font> con tu \<font color="#2166ae">clave de cliente\</font> 1 \<string name="back4app app id">your back4app app id\</string> 2 \<string name="back4app client key">your back4app client key\</string> 2 3) configurar db abre back4app “dashboard” > “core” > “database browser” > “crear una clase” y crea clases de \<font color="#2166ae">personalizado\</font> tipo llamado \<font color="#2166ae">mensaje\</font> y \<font color="#2166ae">chatthread\</font> ; 2 4) configurar consulta en vivo regresa a tu cuenta de back4app https //dashboard back4app com/apps/#!/admin presiona el \<font color="#2166ae">configuración del servidor\</font> botón en tu aplicación encuentra el bloque “alojamiento web y consulta en vivo” abre la configuración de consulta en vivo y verifica la \<font color="#2166ae">activar alojamiento\</font> opción elige un nombre para tu subdominio para activar la consulta en vivo para las 2 clases que creaste \<font color="#2166ae">mensaje\</font> y \<font color="#2166ae">chatthread\</font> copia el nuevo nombre de tu subdominio y haz clic en el botón guardar regresa a \<font color="#2166ae">/app/src/main/res/values/strings xml\</font> y pega “nombre de subdominio” que ingresaste arriba en el \<font color="#2166ae">back4app live query url\</font> en lugar de “tunombredesubdominio” \<string name="back4app live query url">wss\ //yoursubdomainname back4app io/\</string> después de estos pasos, podrás presionar el botón ejecutar en android studio y hacer que el ejemplo funcione usa un emulador o un dispositivo real para probarlo 3 ejecutar la demostración limpia para ver el resultado de ejecutar la versión limpia de la demostración, necesitarás registrar 2 usuarios; iniciar una conversación entre ellos y enviar un par de mensajes; 3\ abre back4app “dashboard” > “core” > “database browser” > “message” si todo funcionó, deberías ver la aplicación de mensajería de chat apareciendo registra dos usuarios y envía algunos mensajes entre ellos deberías ver nuevos datos apareciendo en la \<font color="#2166ae">mensaje\</font> clase ten en cuenta que puedes ver en el servidor de qué están chateando tus usuarios siguiente cierra tu interfaz de chat y pasa al siguiente paso agregar cifrado e2ee ¡ahora, cifremos esos mensajes de extremo a extremo! al final de esta parte, así es como se verán tus mensajes de chat en el servidor ¿puedes notar la diferencia? ¿cómo llegamos allí? obviamente, necesitamos implementar cifrado de extremo a extremo, lo que significa que nuestra aplicación necesita generar el par de claves privada y pública como parte del registro almacenar la clave privada en el almacenamiento de claves en el dispositivo del usuario publicar la clave pública en el servicio de tarjetas de virgil como una “tarjeta virgil” para que otros usuarios la descarguen y cifren mensajes con ella cifrar mensajes con la clave pública y firmar con la clave privada; descifrar mensajes con la clave privada y verificar con la clave pública para esto, necesitaremos agregar e3kit a nuestra aplicación de demostración limpia y algo más de código para implementar todo lo que se describió anteriormente pero antes de comenzar, aclaremos dos términos importantes para ti ¿qué es una tarjeta virgil y una clave privada? tarjeta virgil las tarjetas virgil llevan las claves privadas de los usuarios las tarjetas virgil se publican en el servicio de tarjetas de virgil (imagina que este servicio es como una guía telefónica) para que otros usuarios las recuperen alice necesita recuperar la clave pública de bob para cifrar un mensaje para bob usando esa clave clave privada una parte privada de la clave de cifrado recuerda, las claves privadas pueden descifrar datos que fueron cifrados usando la clave pública correspondiente 1 agregar e3kit a la demostración limpia de e3kit back4app kotlin en el nivel de la aplicación ( \<font color="#2166ae">módulo app\</font> ) gradle en \<font color="#2166ae"> /app/build gradle\</font> añade (pero no sincronices los scripts de gradle todavía) implementación "com virgilsecurity\ ethree $rootproject ext ethree" añade lo siguiente al final de tu nivel de proyecto \<font color="#2166ae">/build gradle\</font> ( \<font color="#2166ae">proyecto chat back4app android\</font> ) 1 ext { 2 ethree = "2 0 5" 3 } ahora puedes sincronizar los scripts de gradle; actualiza tu \<font color="#2166ae">appvirgil\</font> clase añadiendo nuevos campos 1 compañero objeto { 2 lateinit var ethree ethree 3 fun isethreeinitialized () = ethree isinitialized 4 } presione \<font color="#2166ae">alt+ enter\</font> para importar las bibliotecas necesarias en la clase 2 autenticar usuarios con back4app cloud code en \<font color="#2166ae"> /virgilsecurity/virgilback4app/model/\</font> directorio, crea clases de datos \<font color="#2166ae">authenticateresponse\</font> y \<font color="#2166ae">virgiljwtresponse\</font> que representan respuestas de las funciones de cloud code 1 clase de datos authenticateresponse ( val authtoken string ) 2 3 clase de datos virgiljwtresponse ( val virgiltoken string ) en \<font color="#2166ae"> /virgilsecurity/virgilback4app/util/\</font> crea un \<font color="#2166ae">authrx\</font> objeto que implementa llamadas a funciones de cloud code (no olvides importar todas las bibliotecas necesarias después) 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 almacenar virgil jwt localmente el token de virgil recibido de las funciones de cloud code necesita ser almacenado localmente actualicemos \<font color="#2166ae">preferencias\</font> clase en \<font color="#2166ae"> /virgilsecurity/virgilback4app/util/ \</font> definir constante 1 private const val key virgil token = "key virgil token" agregar funciones \<font color="#2166ae">setvirgiltoken\</font> , \<font color="#2166ae">virgiltoken\</font> y \<font color="#2166ae">clearvirgiltoken\</font> 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 modificar el registro de usuario e3kit se encarga de tus claves privadas y públicas para generarlas durante el proceso de registro, necesitaremos hacer lo siguiente en \<font color="#2166ae"> /virgilsecurity/virgilback4app/util/\</font> crea \<font color="#2166ae">rxethree\</font> clase 1 clase rxethree ( val contexto context ) { 2 3 privado val preferencias = preferences instance (context) 4 } ahora, añade \<font color="#2166ae">initethree\</font> función que inicializa la instancia de e3kit en \<font color="#2166ae">rxethree\</font> clase 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 } añadir \<font color="#2166ae">registerethree\</font> función que registra un nuevo usuario en \<font color="#2166ae">rxethree\</font> clase e3kit genera un par de claves durante un registro la clave privada generada se almacena en el almacenamiento local, y la clave pública se publica en los servicios de virgil como una tarjeta de virgil 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 } hagamos algunas actualizaciones a \<font color="#2166ae">loginpresenter\</font> clase (en \<font color="#2166ae"> /virgilsecurity/virgilback4app/auth/)\</font> agregar \<font color="#2166ae">rxethree\</font> campo 1 private val rxethree = rxethree(context) actualiza la \<font color="#2166ae">requestsignup\</font> función para ejecutar el registro con e3kit 1 fun requestsignup(identity string, onsuccess () > unit, onerror (throwable) > unit) { 2 val password = generatepassword(identity tobytearray()) 3 4 val disposable = rxparse signup(identity, password) 5 subscribeon(schedulers io()) 6 observeon(schedulers io()) 7 // new code >> 8 tosingle { parseuser getcurrentuser() } 9 flatmap { authrx virgiljwt(it sessiontoken) } 10 map { preferences setvirgiltoken(it) } 11 flatmap { rxethree initethree(identity) } 12 map { appvirgil ethree = it } 13 flatmap { rxethree registerethree() tosingle { unit } } 14 // << new code 15 observeon(androidschedulers mainthread()) 16 // updated code >> 17 subscribeby( 18 onsuccess = { 19 onsuccess() 20 }, 21 onerror = { 22 onerror(it) 23 } 24 ) 25 // << updated code 26 27 compositedisposable += disposable 28 } 5 modificar funciones de inicio de sesión ahora, hagamos cambios en el \<font color="#2166ae">requestsignin\</font> método de \<font color="#2166ae">loginpresenter\</font> clase (en \<font color="#2166ae"> /virgilsecurity/virgilback4app/auth/)\</font> 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 obtener la lista de chats existentes a continuación, agregue funciones que manejen la inicialización de e3kit en \<font color="#2166ae">threadslistfragment\</font> clase (en \<font color="#2166ae"> /virgilsecurity/virgilback4app/chat/contactslist/)\</font> 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 } actualizar \<font color="#2166ae">postcreateinit\</font> función para inicializar 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 } y agrega el siguiente código en \<font color="#2166ae">threadslistfragmentpresenter\</font> clase en \<font color="#2166ae">virgilsecurity virgilback4app chat contactslist/\</font> agregar campo 1 private val rxethree = rxethree(context) y función 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 } en este punto, podemos registrar/iniciar sesión a un usuario y crear un nuevo chat con otro usuario ahora añadamos cifrado para nuestros mensajes 7 cifrado y descifrado de mensajes añadamos \<font color="#2166ae">findcard\</font> función a \<font color="#2166ae">rxethree\</font> clase (en \<font color="#2166ae"> /virgilsecurity/virgilback4app/util/\</font> ) que nos ayudará a obtener la última tarjeta de virgil por nombre de usuario 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 } cuando se abre un chat, debemos obtener la tarjeta de virgil del destinatario editar \<font color="#2166ae">postcreateinit\</font> de \<font color="#2166ae">chatthreadfragment\</font> clase (en \<font color="#2166ae"> /virgilsecurity/virgilback4app/chat/thread/\</font> ) reemplazando 1 presenter requestmessages(thread, 2 50, 3 page, 4 const tablenames created at criteria, 5 ongetmessagessuccess, 6 ongetmessageserror) código con uno nuevo 1 presenter requestcard(recipientid, 2 ongetcardsuccess, 3 ongetcarderror) y añade dos funciones 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 } ahora cambiemos \<font color="#2166ae">chatthreadpresenter\</font> añadir campos 1 private val ethree = appvirgil ethree 2 private lateinit var usercard card 3 private val rxethree = rxethree(context) agrega una función que obtenga una tarjeta virgil del destinatario 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 } agrega cifrado de mensajes salientes en \<font color="#2166ae">requestsendmessage\</font> función 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 } agrega la descifrado de todos los mensajes entrantes en \<font color="#2166ae"> chatthreadrvadapter\</font> clase (en \<font color="#2166ae"> /virgilsecurity/virgilback4app/chat/thread/)\</font> agregar campos 1 private var ethree ethree = appvirgil ethree 2 lateinit var interlocutorcard card implementar la descifrado de mensajes en \<font color="#2166ae">onbindviewholder\</font> función 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 ejecutar la demostración completa de cifrado de extremo a extremo ahora, para ver el resultado de nuestra demostración completamente cifrada de extremo a extremo, sigue estos pasos nuevamente cerrar sesión del usuario anterior registrarse 2 nuevos usuarios; iniciar una conversación entre ellos y enviar un par de mensajes; abrir back4app “dashboard” > “core” > “database browser” > “message” ¡importante! tienes que cerrar sesión del usuario actual y registrar dos nuevos usuarios, después de eso puedes comenzar el chat e2ee con esos dos nuevos usuarios la razón es que tus dos primeros usuarios no tienen \<font color="#2166ae">virgil card\</font> ’s, así que no puedes usar cifrar\descifrar para ellos { blockquote tip} ¡hecho! ahora puedes ver que los mensajes de los usuarios están cifrados y solo pueden ser accedidos en la aplicación por los propios usuarios cumplimiento de hipaa y gdpr el cifrado de extremo a extremo es una forma de cumplir con los requisitos técnicos de hipaa (la ley de portabilidad y responsabilidad de seguros de salud de los estados unidos de 1996) y gdpr (el reglamento general de protección de datos de la unión europea) si necesitas más detalles, regístrate para obtener una cuenta de virgil https //developer virgilsecurity com/account/signup?utm source=back4app\&utm medium=blog\&utm campaign=e2eechat , únete a nuestra comunidad de slack y contáctanos allí estamos felices de discutir tus propias circunstancias de privacidad y ayudarte a entender lo que se requiere para cumplir con los requisitos técnicos de hipaa y gdpr ¿a dónde ir desde aquí? proyecto final https //github com/virgilsecurity/chat back4app android/ si te perdiste piezas del rompecabezas, abre la rama del proyecto e2ee puedes insertar tus credenciales de aplicación en este código (como hiciste durante el artículo) y construir el proyecto puedes encontrar más información sobre lo que puedes construir con virgil security aquí https //virgilsecurity com/?utm source=back4app\&utm medium=blog\&utm campaign=e2eechat