ReactiveX + Meteor 종단간 암호화 구현 사례

Appsoulute 이재호

@acidsound

30분 동안 Micro-Social-Networking 서비스 만들기
라이브 코딩

여러분에게

팔아야할 약이 이만~~~큼

Reactive Programing

Rx

Meteor

E2E Encryption

Declarative Programming

PublicKey

Javascript Core

DDP

TweetNacl

Functional

Reactive Programing

Rx

Meteor

E2E Encryption

Declarative Programming

PublicKey

Javascript Core

DDP

TweetNacl

Functional

역시 Meteor

Meteor란?

Meteor란?

Full-Stack Javascript Platform

Meteor란?

Reactive Full-Stack Javascript Platform

바쁘신 분들을 위해 결론 먼저

1. Meteor로

실시간 동시 사용자

앱+서버를 빠르게 개발

2. 클라이언트가

웹이 아닌 경우

ReactiveX

Reactive Programming?

Reactive Programming이란 데이터 흐름과 변화 전파에 중점을 프로그래밍 패러다임입니다. , 프로그래밍 언어에서 정적 또는 동적 데이터 흐름을 쉽게 표현할 있어야하며 변경 사항을 데이터 흐름을 통해 자동으로 전파한다는 것을 의미합니다.

It is convenient to distinguish roughly between three kinds of computer programs. Transformational programs compute results from a given set of inputs; typical examples are compilers or numerical computation programs. Interactive programs interact at their own speed with users or with other programs; from a user point of view, a time-sharing system is interactive. Reactive programs also maintain a continuous interaction with their environment, but at a speed which is determined by the environment, not the program itself. Interactive programs work at their own pace and mostly deal with communication, while reactive programs only work in respond to external demands and mostly deal with accurate interrupt handling. Real-time programs are usually reactive. However, there are reactive programs that are not usually considered as being real-time, such as protocols, system drivers, or man-machine interface handlers.

Gérard Berry - INRIA Fr.

예를 들면

명령형 프로그래밍

Imperative programming

명령형 프로그래밍

  • a = 1 이랜다
  • b = 2 랜다
  • c = a + b 라고 하면
  • c가 3 라고 한다
  • a = 4 라고 했는데
  • c는 그래도 3?????

왜죠?
왜왜왜?
왜인거죠?

SpreadSheet

(aka. excel)

변경 사항이 자동으로 적용

function 으로 맛보기 (coffee/ecma6)

a = 1
b = 2
c = a + b
c
3
a = 3
c
3
a = -> 1
b = -> 2
c = -> a() + b()
c()
3
a = -> 3
c()
5

a = ()=> 1
b = ()=> 2
c = ()=> a() + b()
c()
3
a = ()=> 3
c()
5

Reactive Programming in Meteor

Reactive Source

+

Reactive Computation

Reactive Source

개 소변 훈련.

- 오줌 마려울 때 마다 짖게 한다.

- 배변 패드로 이동

 

Reactive JavaScript 객체

- 변경될 때 마다 알려준다.

- 변경이 일어나면 특정 명령을 실행

Reactive Computations

물론 개가 아무리 짖는 다고 해도 당신이 집에 없으면?

마찬가지로 Reactive data sources는 변경이 있을 때 마다 해당 데이터를 수신 대기함.

이 곳이 Reactive Context.

변경이 일어나면 실행하는 코드 블록을 Reactive Computation이라고 한다.

Meteor ReactiveCode

/* reactive datasource 인 ReactiveVar를 선언 */
let someValue = new ReactiveVar();

/* Reactive Computation. 변경이 일어나면 console.log에 출력 */
Tracker.autorun(()=>console.log(someValue.get()));

/* reactive datasource의 변경 */
someValue.set("Hello");

> Hello

someValue.set("Hello");

/* 변경이 일어나지 않으면 Reactive Computation도 일어나지 않는다 */

하지만

이것만으로 부족하다!

(서버 없이 클라이언트만 할 것이 아니라면)

실시간 어플리케이션

실시간 동시 사용자
어플리케이션

변경 동기화

DB 저장

DB 변경 감지

변경 전달

DDP

Distributed Data Protocol

DDP 구성요소

  • Publish
  • Subscribe
  • Method  - RPC
    (Remote Procedure Call)

Subscribe 요청

관심 주제만 들을래

Publish 연결

ㅇㅇ 필터링 해줄께

Observe

빨대꽂기

(지속적 변경 반영)

영웅은 죽지 않아요.

Method call(RPC)

DB 적용

변경 감지

subscribe 전송

E2E Encryption

종단간 암호화

Telegram 망명사태

지금은 상식!

(aka. 비밀채팅)

저장소로부터 대상이 탈취되거나 감청 당해도 복호화 할 수 없어야한다

그..그렇군요;

친구에게 선의로 해준거라 암호도 안걸었지만...

어떻게?

2개의 상자

SecretBox

Box

직접 해봅시다!

Secretbox: secret-key authenticated encryption

Message

Key

SymNonce

암호화

복호화

Box: public-key authenticated Encryption

Message

SecretKey
(Privatekey)

AsymNonce

PublicKey

userPK Created using Figma

Box: public-key authenticated Encryption

Message

SecretKey
(Privatekey)

AsymNonce

PublicKey

userPK Created using Figma

암호화

복호화

1

2

3

4

5

1

5

6

순서대로 생성하고 복사해봅니다.

SecretBox
빠른 속도

키 전달 문제

Box
안전한 키 전달

복잡+느리다

그렇다면

Key

SymNonce

Message

SecretKey
(Privatekey)

AsymNonce

PublicKey

userPK Created using Figma

EncMessage

EncMessage

Message

Key

SymNonce

Message

SecretKey
(Privatekey)

AsymNonce

PublicKey

userPK Created using Figma

EncMessage

EncMessage

Key

SecretBox로 암호화 Key를 Box로 전달

Box로 복호화 한 Key로 SecretBox를 복호화

키전달은 공개키

복호화는 대칭키

PROFIT! 쬲

실제로 이것보단 조금 더

복잡하긴 해요...

사용자의 개인키 보관/복원

패스워드 변경

수신자의 인원 변경

과거 메시지 정책 등등

구현

userA가 userB에게 암호화한 메시지를 보낸다.

client meteor

server meteor

userPK Created using Figma

mongoDB

sub

pKey

1. 대화방 진입

sub

pKey

sub

room

sub

room

userB

userA

client meteor

server meteor

userPK Created using Figma

mongoDB

2. 사용자 공개키 요청

pub

pKey

userPK Created using Figma
userPK Created using Figma

pub

room

userB

userA

client meteor

server meteor

userPK Created using Figma

mongoDB

3. Document key 생성

userPK Created using Figma
userPK Created using Figma

userB

userA

client meteor

server meteor

userPK Created using Figma

mongoDB

4. Encrypt document key

userPK Created using Figma
userPK Created using Figma

DDP MAGIC!

userB

userA

client meteor

server meteor

userPK Created using Figma

mongoDB

5. Document key 구조

userPK Created using Figma
userPK Created using Figma

userB

userA

client meteor

server meteor

userPK Created using Figma

mongoDB

6. Decrypt Document key

userPK Created using Figma
userPK Created using Figma

userB

userA

client meteor

server meteor

userPK Created using Figma

mongoDB

7. get Document key

userPK Created using Figma
userPK Created using Figma

userB

userA

client meteor

server meteor

userPK Created using Figma

mongoDB

8. message 생성

abcdefghijklmnopqrst...
userPK Created using Figma
userPK Created using Figma

userB

userA

client meteor

server meteor

userPK Created using Figma

mongoDB

9. Encrypt message

abcdefghijklmnopqrst...
userPK Created using Figma
userPK Created using Figma

DDP MAGIC!

userB

userA

client meteor

server meteor

userPK Created using Figma

mongoDB

10. Get Encrypted message

abcdefghijklmnopqrst...
userPK Created using Figma
userPK Created using Figma
abcdefghijklmnopqrst...

userB

userA

client meteor

server meteor

userPK Created using Figma

mongoDB

11. Decrypt message

abcdefghijklmnopqrst...
userPK Created using Figma
userPK Created using Figma
abcdefghijklmnopqrst...

userB

userA

client meteor

server meteor

userPK Created using Figma

mongoDB

12. Get decrypted message

abcdefghijklmnopqrst...
userPK Created using Figma
userPK Created using Figma
abcdefghijklmnopqrst...

userB

userA

최고다 리액티브짱!

Mobile

쉽게 갈까요?

아니오

얜 못 믿겠는데요

Native로 갑시다

하지만...

Meteor 밖은 "위험"해 ㄷㄷ

Async
Serialize
Exception

RectiveX

An API for asynchronous programming
with observable streams

RectiveX

누가 만들었나?

믿을 만한
마우스/키보드 전문회사
 Microsoft

Polyglot

고생은 한번이면 족할...까?

ReactiveX support...

ReactiveX support...

Map, Filter, Promise 정도는 써봤으니

대충 비슷하지 않을까?

아니야...

갑시다 Native!

큰그림

WebSocket

DDP

Rx

Rx+Meteor(DDP)

  • Login
  • Logout
  • User Profile
  • Publish
  • Subscribe
  • Method
  • ...Validations

RxDDP

login packet example

method$ = WebSocketResponseObservable.filter o-> o.msg is 'result'

collection$ = WebSocketResponseObservable.filter o-> o.collection

14:44:42.660   {"msg":"method","method":"login","params":
  [{"resume":"3MFpDmTtUXXkmKR5JJ0OUJODb_O19BzFXcLRu0JIqmd"}]
  ,"id":"1"}
14:44:42.827 a {"msg":"added","collection":"users","id":"pJdkcRjHTGmKzE9hv"}
14:44:42.829 a {"msg":"changed","collection":"users","id":"pJdkcRjHTGmKzE9hv",
  "fields":{
    "emails":[{"address":"jhee@appsoulute.com","verified":false}]
  }}
14:44:42.830 a {"msg":"updated","methods":["1"]}
14:44:42.842 a {"msg":"result","id":"1","result":{
  "id":"pJdkcRjHTGmKzE9hv",
  "token":"3MFpDmTtUXXkmKR5JJ0OUJODb_O19BzFXcLRu0JIqmd",
  "tokenExpires":{"$date":1484372528136}
}}

UI / Data 의 분리

RPC (Remote Procedure Call) 한 뒤 callback을 기다리지 않음

Meteor server에서 내려주는 data stream에만 반응

Application Structure

LoginView

RxMeteor

ProfileView

MessagesView

methodObservable

collectionObservable

ㄴ usersObservable

ㄴ messagesObservable

subscribeObservable

logoutMethodCall

changePasswordMethodCall

usersSubscribe

loginMethodCall

signUpMethodCall

usersSubscribe

messagesSubscribe

usersSubscribe

sendMessageMethodCall

Login의 경우

  1. local에서 Unique ID를 생성 (method ID)
  2. Login method를 method ID와 함께 call함
  3. methodObservable 중 method ID로 필터
  4. 3을 subscribe 하고 onNext일때 메인 화면 이동
/* login Method call */
{"msg":"method","method":"login","params":[
  {"user":{"username":"admin"},"password":
    {"digest":"ㄹㄹㄹㄹ","algorithm":"sha-256"}}],
  "id":"1"}

/* result */
{"msg":"result","id":"1","result":{
  "id":"kx4SooGR5avtZDWJN",
  "token":"ZMUvf03-buGVnblochaafOi1-BCrGcIoCMf9Buo9l4p",
  "tokenExpires":{"$date":1488373375267}
}}

Logout의 경우

  1. login에서 받은 자신의 userId를 알고 있음
  2. usersObservable중 id가 userId인 것을 필터
  3. 자신의 id가 removed 일때 logout 처리 (result와 무관)
  4. 현재 화면 위치와 상관없이 logout 처리가 가능!
    같은 사용자가 다른 장비로 동시 접속시 처리
/* Logout method call */
{"msg":"method","method":"logout","params":[],"id":"2"}

/* subscribed collection */
{"msg":"removed","collection":"users","id":"kx4SooGR5avtZDWJN"}

/* result of method */
{"msg":"method","method":"logout","params":[],"id":"2"}

유용한 Rx Pattern

CombineLatest

validation

Debounce

연타방지

DistinctUntilChanged

중복방지

Scan

State Store - reduce

Scan

State Store - reduce

오늘의 나는 태어날 때의 나부터

어제의 나까지 리듀스 한 것

FlatMap

Serialize

1st start

2nd start

1st end

3rd start

2nd end

3rd end

ConcatMap

Serialize (10단콤보!)

1st start

1st end

2nd start

2nd end

3rd start

3rd end

Example 대방출

이정도로 시작해도 좋아요 <3

Rx Reference

결론

실시간 프로그래밍은

어렵다

실시간 프론트엔드

프로그래밍은

어렵다

실시간 프론트엔드

다중 사용자

프로그래밍은 어렵다

실시간 풀스택

다중 사용자

프로그래밍은 어렵다

Reactive Programming 하세요

Meteor

full-stack reactive javascript platform

Meteor

full-stack reactive javascript platform

ReactiveX

An API for asynchronous programming
with observable streams

Meteor

full-stack reactive javascript platform

ReactiveX

An API for asynchronous programming
with observable streams

고맙습니다

Thank you

참조

rxmeteor_e2e

By Lee Jaeho

rxmeteor_e2e

ReactiveX + Meteor 종단간 암호화 구현 사례

  • 2,405