Security & Privacy
GDPR 준수 안드로이드 앱 개발 가이드 - 암호화와 E2EE
50 분
gdpr 준수 채팅 앱 만들기 소개 안녕하세요 back4app 커뮤니티! 이것은 virgil security, inc https //virgilsecurity com/?utm source=back4app\&utm medium=blog\&utm campaign=e2eechat 우리는 twilio의 종단 간 암호화 메시징 https //www twilio com/blog/2016/05/introducing end to end encryption for twilio ip messaging with virgil security html 우리의 친구 @ back4app이 종단 간 암호화 채팅 앱을 back4app 위에 구축하는 방법을 보여달라고 요청했습니다 이 게시물에서는 간단한 back4app android 메신저 앱을 종단 간 암호화하는 단계를 안내해 드리겠습니다! 준비되셨나요? ps 세부 사항이 중요하지 않다면, 게시물 끝으로 건너뛰고 최종 제품을 다운로드하세요 종단 간 암호화란 무엇인가? 먼저, e2ee(종단 간 암호화)가 무엇인지와 어떻게 작동하는지 간단히 복습해 보겠습니다 e2ee는 간단합니다 채팅 메시지를 입력하면 모바일 장치(또는 브라우저)에서 암호화되고, 채팅 파트너가 수신하여 채팅 창에 표시하고자 할 때만 복호화됩니다 메시지는 wi fi와 인터넷을 통해 클라우드/웹 서버를 거쳐 데이터베이스로 이동하고 다시 채팅 파트너에게 돌아가는 동안 암호화된 상태로 유지됩니다 다시 말해, 두 사람이 무엇에 대해 채팅하고 있는지 네트워크나 서버는 전혀 알지 못합니다 종단 간 암호화에서 어려운 점은 채팅에 참여하는 사용자만 접근할 수 있도록 암호화 키를 관리하는 작업입니다 내가 “다른 누구도”라고 쓸 때, 정말로 그렇게 말하는 것입니다 클라우드 제공업체의 내부자나 심지어 당신, 개발자조차도 접근할 수 없습니다; 우연한 실수는 없다 https //techcrunch com/2017/11/29/meet the man who deactivated trumps twitter account/ 또는 법적으로 강제된 엿보기가 가능합니다 암호화 작업, 특히 여러 플랫폼을 위한 암호화 작업은 어렵습니다 진정한 난수를 생성하고, 올바른 알고리즘을 선택하고, 올바른 암호화 모드를 선택하는 것은 대부분의 개발자들이 손을 흔들고 결국 그냥 하지 않게 만드는 몇 가지 예일 뿐입니다 이 블로그 게시물에서는 이러한 성가신 세부 사항을 무시하고 virgil의 sdk를 사용하여 빠르고 간단하게 종단 간 암호화를 수행하는 방법을 보여줍니다 소개로, 우리는 back4app의 메신저 앱을 종단 간 암호화로 업그레이드하는 방법은 다음과 같습니다 가입 시 새로운 사용자에 대한 개별 개인 키 및 공개 키를 생성합니다 (기억하세요 수신자의 공개 키가 메시지를 암호화하고 일치하는 수신자의 개인 키가 이를 복호화합니다) 메시지를 보내기 전에, 수신자의 공개 키로 채팅 메시지를 암호화합니다 메시지를 받은 후, 수신자의 개인 키로 채팅 메시지를 복호화합니다 우리는 사용자의 공개 키를 virgil의 카드 서비스에 게시하여 채팅 사용자가 서로를 조회하고 서로에게 메시지를 암호화할 수 있도록 합니다 개인 키는 사용자 장치에 남아 있습니다 간단하게 유지하세요 이것은 e2ee 채팅의 가장 간단한 구현이며, 2명의 사용자 간의 간단한 채팅 앱에 완벽하게 작동합니다 대화가 짧고 개인 키가 있는 장치를 잃어버리면 메시지 기록을 잃어버려도 괜찮습니다 좋아요, 충분히 이야기했어요! 이제 코딩을 시작해봅시다 안드로이드 앱의 설정을 안내하겠습니다 그 다음, 앱을 종단 간 암호화하도록 코드를 추가하겠습니다 전제 조건 이 튜토리얼을 완료하려면 다음이 필요합니다 안드로이드 스튜디오 back4app에서 생성된 앱 다음의 새 앱 만들기 튜토리얼 을 따라 back4app에서 앱을 만드는 방법을 배우세요 virgil security 계정 에 가입하세요 (나중에 앱을 생성할 것입니다) “클린” back4app 메신저 앱 설정하기 1 앱 서버 설정하기 클라우드 기능 배포부터 시작하겠습니다 이를 위해서는 다음이 필요합니다 찾기 main js main js 및 package json package json 에서 scripts scripts 디렉토리; 열기 main js main js 좋아하는 편집기로 1 1) back4app 자격 증명 받기 열기 대시보드 대시보드 앱의 > 앱 설정 앱 설정 > 보안 및 키 보안 및 키 메인에서 main js main js , parse app id parse app id 를 당신의 애플리케이션 id 애플리케이션 id 로 교체하고 parse rest api key parse rest api key 를 당신의 rest api 키 rest api 키 1 2) virgil 자격 증명 가져오기 다음에서 애플리케이션을 생성하세요 virgil 대시보드 https //dashboard virgilsecurity com/ 새로운 virgil 애플리케이션을 열고 e3kit 섹션으로 이동하여 env env 파일을 왼쪽 사이드바의 e3kit 섹션 아래에 생성합니다 다음의 값을 복사합니다 app id app id , app key app key , 그리고 app key id app key id 를 env env 파일에서 복사합니다 복사한 값을 main js main js 파일의 해당 필드( main js main js 의 scripts scripts 디렉토리에 교체하세요 1 3) 클라우드 코드 함수를 배포하세요 back4app “대시보드”를 열고 > “코어” > 클라우드 코드 함수; 클릭하여 +add를 선택하고 main js 및 package json(스크립트 디렉토리에서)을 선택한 후, 두 파일을 클라우드 폴더로 이동합니다; deploy를 클릭합니다 2 클린 back4app kotlin 데모 앱 시작하기 먼저 back4app 클라우드 코드 기능을 설정하는 것을 잊지 마세요 이것은 이 데모의 필수 부분입니다 그 후, 다음 단계를 진행하세요 2 1) android studio에서 프로젝트 가져오기 android studio 열기 > 파일 파일 > 새로 만들기 새로 만들기 > 버전 관리에서 프로젝트 버전 관리에서 프로젝트 > git git git 저장소 url https //github com/virgilsecurity/chat back4app android 다음 clean chat kt clean chat kt 브랜치를 체크아웃합니다 중요! “프로젝트” 유형의 파일 트리를 선택하세요 이 튜토리얼 전반에 걸쳐 사용됩니다 2 2) 프로젝트에 back4app 자격 증명 설정하기 back4app “대시보드”에서 앱 > “앱 설정” > “보안 및 키”를 엽니다; “ /app/src/main/res/values/strings xml /app/src/main/res/values/strings xml 파일로 이동하여 your back4app app id your back4app app id 을(를) application id application id 로 교체하고 your back4app client key your back4app client key 을(를) client key client key 로 교체하십시오 2 3) db 설정 back4app “대시보드” > “코어” > “데이터베이스 브라우저” > “클래스 생성”을 열고 custom custom 유형의 클래스를 생성하십시오 message message 및 chatthread chatthread ; 2 4) 라이브 쿼리 설정 당신의 back4app 계정 https //dashboard back4app com/apps/#!/admin 애플리케이션에서 서버 설정 서버 설정 버튼을 누르세요 “웹 호스팅 및 라이브 쿼리” 블록을 찾으세요 라이브 쿼리 설정을 열고 호스팅 활성화 호스팅 활성화 옵션을 확인하세요 당신이 생성한 2개의 클래스에 대해 라이브 쿼리를 활성화할 서브도메인 이름을 선택하세요 메시지 메시지 및 채팅 스레드 채팅 스레드 새 서브도메인 이름을 복사하고 저장 버튼을 클릭하세요 다시 /app/src/main/res/values/strings xml /app/src/main/res/values/strings xml 로 돌아가서 위에 입력한 “서브도메인 이름”을 back4app live query url back4app live query url 대신 “yoursubdomainname”에 붙여넣으세요 이 단계가 끝나면 android studio에서 실행 버튼을 눌러 샘플을 작동시킬 수 있습니다 에뮬레이터나 실제 장치를 사용하여 테스트해 보세요 3 클린 데모 실행 클린 버전의 데모를 실행한 결과를 보려면 다음을 수행해야 합니다 2명의 사용자를 등록하세요; 그들 사이에 대화를 시작하고 몇 개의 메시지를 보내세요; 3\ back4app “대시보드” > “코어” > “데이터베이스 브라우저” > “메시지”를 엽니다 모든 것이 잘 작동했다면, 채팅 메신저 앱이 나타나는 것을 볼 수 있어야 합니다 두 사용자를 등록하고 서로 몇 개의 메시지를 보내세요 메시지 메시지 클래스에 새로운 데이터가 나타나는 것을 볼 수 있어야 합니다 서버에서 사용자가 어떤 대화를 나누고 있는지 볼 수 있다는 점에 유의하세요 다음 채팅 인터페이스를 닫고 다음 단계로 넘어가세요 – e2ee 암호화 추가 이제 메시지를 종단 간 암호화해 보겠습니다! 이 부분이 끝날 무렵, 서버에서 채팅 메시지가 이렇게 보일 것입니다 차이점을 찾을 수 있나요? 어떻게 거기에 도달할 수 있을까요? 분명히, 우리는 종단 간 암호화를 구현해야 하며, 이는 우리의 앱이 다음을 필요로 한다는 것을 의미합니다 회원가입의 일환으로 개인 키와 공개 키 쌍을 생성합니다 사용자의 장치의 키 저장소에 개인 키를 저장합니다 다른 사용자가 다운로드하고 메시지를 암호화할 수 있도록 virgil의 카드 서비스에 공개 키를 'virgil 카드'로 게시합니다 공개 키로 메시지를 암호화하고 개인 키로 서명합니다; 개인 키로 메시지를 복호화하고 공개 키로 검증합니다 이를 위해, 우리는 우리의 깔끔한 데모 애플리케이션에 e3kit을 추가하고 위에서 설명한 모든 것을 구현하기 위해 추가 코드를 작성해야 합니다 하지만 시작하기 전에, 두 가지 중요한 용어를 명확히 해보겠습니다 virgil 카드와 개인 키란 무엇인가요? virgil 카드 virgil 카드에는 사용자의 개인 키가 포함되어 있습니다 virgil 카드는 virgil의 카드 서비스에 게시됩니다 (이 서비스를 전화번호부와 같다고 상상해 보세요) 다른 사용자가 이를 검색할 수 있도록 앨리스는 밥을 위해 메시지를 암호화하기 위해 밥의 공개 키를 검색해야 합니다 개인 키 암호화 키의 개인 부분입니다 개인 키는 일치하는 공개 키를 사용하여 암호화된 데이터를 복호화할 수 있습니다 1 e3kit을 깔끔한 e3kit back4app kotlin 데모에 추가하기 앱 수준에서 ( 모듈 app 모듈 app ) gradle에서 /app/build gradle /app/build gradle 추가하세요 (하지만 gradle 스크립트는 아직 동기화하지 마세요) 다음 내용을 프로젝트 수준의 /build gradle /build gradle ( 프로젝트 chat back4app android 프로젝트 chat back4app android )에 추가하세요 이제 gradle 스크립트를 동기화할 수 있습니다; 다음 필드를 추가하여 appvirgil appvirgil 클래스를 업데이트하세요 클래스에 필요한 라이브러리를 가져오려면 alt+ enter alt+ enter 를 누르세요 2 back4app cloud code로 사용자 인증하기 다음 경로에 있는 /virgilsecurity/virgilback4app/model/ /virgilsecurity/virgilback4app/model/ 디렉토리에서 authenticateresponse authenticateresponse 및 virgiljwtresponse virgiljwtresponse 를 생성하여 cloud code 함수의 응답을 나타내세요 다음 경로에 있는 /virgilsecurity/virgilback4app/util/ /virgilsecurity/virgilback4app/util/ 에서 authrx authrx 객체를 생성하여 cloud code 함수에 대한 호출을 구현하세요 (필요한 모든 라이브러리를 가져오는 것을 잊지 마세요) 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 virgil jwt를 로컬에 저장하기 cloud code 함수에서 받은 virgil 토큰은 로컬에 저장해야 합니다 preferences preferences 클래스를 /virgilsecurity/virgilback4app/util/ /virgilsecurity/virgilback4app/util/ 에서 업데이트합시다 상수를 정의합니다 함수를 추가합니다 setvirgiltoken setvirgiltoken , virgiltoken virgiltoken 및 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 사용자 등록 수정 e3kit은 귀하의 개인 키와 공개 키를 관리합니다 등록 과정에서 이를 생성하기 위해 다음과 같은 작업을 수행해야 합니다 다음 위치에서 /virgilsecurity/virgilback4app/util/ /virgilsecurity/virgilback4app/util/ 에 rxethree rxethree 클래스를 생성합니다 이제 initethree initethree 함수를 추가하여 rxethree rxethree 클래스에서 e3kit 인스턴스를 초기화합니다 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 } 새로운 사용자를 registerethree registerethree 클래스에 등록하는 함수를 추가합니다 e3kit은 가입하는 동안 키 쌍을 생성합니다 생성된 개인 키는 로컬 저장소에 저장되고, 공개 키는 virgil services에 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 } 업데이트를 진행합시다 loginpresenter loginpresenter 클래스 (in /virgilsecurity/virgilback4app/auth/) /virgilsecurity/virgilback4app/auth/) 필드를 추가하세요 rxethree rxethree 1 private val rxethree = rxethree(context) 다음의 requestsignup requestsignup 함수를 업데이트하여 e3kit으로 등록을 실행하세요 이제 requestsignin requestsignin 메서드에 변경을 가해 보겠습니다 loginpresenter loginpresenter 클래스 (위치 /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 기존 채팅 목록 가져오기 다음으로, e3kit 초기화를 처리하는 함수를 threadslistfragment threadslistfragment 클래스에 추가합니다 (위치 /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 } 업데이트 postcreateinit postcreateinit 함수로 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 } 다음 코드를 threadslistfragmentpresenter threadslistfragmentpresenter 클래스에 추가하세요 virgilsecurity virgilback4app chat contactslist/ virgilsecurity virgilback4app chat contactslist/ 필드 추가 1 private val rxethree = rxethree(context) 및 함수 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 } 이 시점에서 우리는 사용자를 가입/로그인하고 다른 사용자와 새로운 채팅을 생성할 수 있습니다 이제 우리의 메시지에 대한 암호화를 추가해 보겠습니다 7 메시지 암호화 및 복호화 다음으로 findcard findcard 함수를 rxethree rxethree 클래스에 추가하겠습니다 (위치 /virgilsecurity/virgilback4app/util/ /virgilsecurity/virgilback4app/util/ ) 이 함수는 사용자 이름으로 최신 virgil 카드를 가져오는 데 도움이 될 것입니다 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 } 채팅이 열리면 수신자의 virgil 카드 정보를 얻어야 합니다 postcreateinit postcreateinit 의 chatthreadfragment chatthreadfragment 클래스 ({ /virgilsecurity/virgilback4app/chat/thread/ /virgilsecurity/virgilback4app/chat/thread/ })를 교체하여 1 presenter requestmessages(thread, 2 50, 3 page, 4 const tablenames created at criteria, 5 ongetmessagessuccess, 6 ongetmessageserror) 코드를 새 코드로 교체합니다 1 presenter requestcard(recipientid, 2 ongetcardsuccess, 3 ongetcarderror) 두 개의 함수를 추가하세요 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 } 이제 chatthreadpresenter chatthreadpresenter 필드를 추가하세요 1 private val ethree = appvirgil ethree 2 private lateinit var usercard card 3 private val rxethree = rxethree(context) 수신자의 virgil 카드를 얻는 함수를 추가하세요 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 } 전송되는 메시지의 암호화를 추가하세요 requestsendmessage requestsendmessage 함수에 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 } 모든 수신 메시지의 복호화를 추가하세요 chatthreadrvadapter chatthreadrvadapter 클래스에 (위치 /virgilsecurity/virgilback4app/chat/thread/) /virgilsecurity/virgilback4app/chat/thread/) 필드를 추가하세요 1 private var ethree ethree = appvirgil ethree 2 lateinit var interlocutorcard card 메시지 복호화 구현 onbindviewholder onbindviewholder 함수에서 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 전체 종단 간 암호화 데모 실행 이제 완전한 종단 간 암호화 데모의 결과를 보려면, 다시 이 단계를 진행하세요 이전 사용자 로그아웃 2명의 새로운 사용자 등록; 그들 간의 대화를 시작하고 몇 개의 메시지를 보내세요; back4app “대시보드” > “코어” > “데이터베이스 브라우저” > “메시지”를 엽니다 중요! 현재 사용자를 로그아웃 하고 두 명의 새로운 사용자를 등록해야 합니다 그 후에 이 두 명의 새로운 사용자와 e2ee 채팅을 시작할 수 있습니다 이유는 첫 번째 두 사용자가 virgil 카드 virgil 카드 가 없기 때문에 그들에 대해 암호화\복호화를 사용할 수 없습니다 { blockquote tip} 완료! 이제 사용자의 메시지가 암호화되어 있으며, 앱 내에서 사용자 자신만 접근할 수 있음을 알 수 있습니다 hipaa 및 gdpr 준수 종단 간 암호화는 hipaa(1996년 미국 건강 보험 이동성 및 책임법) 및 gdpr(유럽 연합 일반 데이터 보호 규정)의 기술적 요구 사항을 충족하는 방법입니다 더 자세한 정보가 필요하면 무료로 virgil 계정 https //developer virgilsecurity com/account/signup?utm source=back4app\&utm medium=blog\&utm campaign=e2eechat , 우리의 slack 커뮤니티에 가입하고 그곳에서 문의하세요 우리는 귀하의 개인 정보 상황에 대해 논의하고 hipaa 및 gdpr 기술적 요구 사항을 충족하는 데 필요한 사항을 이해하는 데 도움을 드릴 수 있습니다 이제 어디로 가야 할까요? 최종 프로젝트 https //github com/virgilsecurity/chat back4app android/ 퍼즐의 일부를 놓쳤다면 e2ee 프로젝트 브랜치를 열어보세요 이 코드에 귀하의 애플리케이션 자격 증명을 삽입할 수 있으며(기사에서 했던 것처럼) 프로젝트를 빌드할 수 있습니다 virgil security로 구축할 수 있는 것에 대한 더 많은 정보를 여기 https //virgilsecurity com/?utm source=back4app\&utm medium=blog\&utm campaign=e2eechat 에서 찾을 수 있습니다