Interesting2021. 1. 25. 18:00

우리가 https로 서비스를 제공하는 사이트에 접속할때의 데이터 흐름을 정리해 보겠다.

 

https로 서비스를 제공하기 위해서는 먼저 인증서를 발급받아야 한다. 

이는 인증기관에 등록을 요청하여 발급이 가능하며 매년 재발급시마다 비용을 지불해야 한다.

발급받은 인증서는 웹서버에 설치되어 브라우저에서 접속시마다 일련의 인증과정을 거칠때 사용된다.

 

이 과정 전체를 나타낸 시쿼스다이어그램이다.

 

1. 인증기관(CA)에 인증서 발급요청을 한다.

2. 인증기관은 검토를 거친 후 인증서에 CA공개키와 사이트정보를 포함한 후 CA개인키로 암호화한다.

3. 암호화된 인증서가 발급이된다.

4. C공개키는 브라우저에 제공된다.

 

여기까지가 인증서 발급의 단계이다. 이어서 브라우저에서 접속시의 시나리오는 다음과 같다.

 

5. 브라우저에서 접속을 시도한다.

6. 웹서버는 사이트 인증서를 제공한다.

7. 브라우저는 사이트인증서를 CA공개키로 복호화한다. 복호화하면 사이트공개키를 얻을 수 있다.

8. 브라우저는 대칭키를 생성한다.

9. 브라우저는 사이트공개키로 대칭키를 암호화한다.

10. 웹서버는 암호화된 대칭키를 사이트개인키로 복호화한다.

11. 웹서버는 복호화된 대칭키로 요청받은 웹사이트 리소스들을 암호화하여 응답한다.

12. 브라우저는 암호화된 리소스들을 대칭키로 복호화하여 렌더링한다.

 

6과 7과정에서 웹서버에서 제공한 인증서를 브라우저에서 CA공개키로 복호화 시 복호화가 되고 복호화된 정보가 현재 접속한 사이트 정보와 동일하면 이는 허가된 접근으로 판정이 나게되며 

이 후 통신구간에는 대칭키를 서로 교환하여 통신함으로써 통신시 오버로드를 줄이는 방식으로 프로세스가 진행된다.

 

 

 

 

 

 

 

Posted by 삼스
카테고리 없음2020. 12. 17. 16:56

웹소켓프로토콜로 웹소켓서버와 웹소켓API로 통신할 수 있다.

 

webSocket = new WebSocket(url, protocols);

url : wss:// 스키마사용을 권장하며 보안을 고려하지 않는다면 ws://스키마를 사용해도 된다.
protocols(옵션) : 하나이상의 프로토콜을 지정할 수 있다. 웹소켓의 서브프로토콜을 지정하며 하나이상의 프로토콜을 지정하여 여러가지 유형의 작업을 할 수 있다.

대상이 접근을 허용하지 않으면 보안에러(SecurityError)가 발생한다. 

연결시 에러가 발생하면 onerror가 먼저 발생하고 이어서 onclose가 발생한다.

 

var exampleSocket = new WebSocket("wss://www.example.com/socketserver", "protocol1");
var exampleSocket2 = new WebSocket("wss://www.example.com/socketserver", ["protocol1", "protocol2"]);

exampleSocket.readyState는 CONNECTING상태가 되고 연결이 준비가 되면 OPEN상태로 된다.
연결이 되면 exampleSocket.protocol로 서버에서 선택된 프로토콜을 확인할 수 있다.

전송은 다음과 같이 한다.

exampleSocket.send("서버가 기다리고 있는 메세지")

전송은 문자열과 Blob 또는 ArrayBuffer가 가능하다.

연결은 비동기이고 성공할지 실패할지 알수 없기 때문에 객체 생성후 바로 전송하면 전송을 보장할 수 없다.
따라서 onopen이벤트 핸들러에서 작업해야 한다.

exampleSocket.onopen = function (event) {
    exampleSocket.send("서버가 기다리고 있는 메세지");
}

JSONJSON객체를 전송하고자 한다면 문자열로 치환하여 전송하여야 한다.

 

var msg = {
    type: "message",
    text: "test message"
};

exampleSocket.send(JSON.stringify(msg));

서버로부터의 메세지는 onmessage핸들러에서 가능하다.

exampleSocket.onmessage = function (event) {
  console.log(event.data);
}

웹소켓으로 수신되는 문자셋은 UTF-8포맷이다.

 

웹소켓연결을 종료하려면 close를 호출한다.

exampleSocket.close();

종료하기 전에 bufferedAmount속성을 확인해서 아직 전송하지 않은 데이터가 있는지 확인할 수 있다. 0인경우 아직 남은것으로 판단하면 된다.

 

비보안연결과 보안연결을 혼합하여 사용할 수 없다. 브라우저들이 이런 경우를 허용하지 않는다.

 

 

Posted by 삼스
Android2020. 9. 8. 11:09

Android 10(Q, 29 level)으로 TargetApi로 설정한 앱이 Android10이상의 단말에 설치된 경우 외부저장소에 대해 Scoped storage모드로 동작한다.

 

Scoped Stroage

 

Android10 타겟에 Android10 단말에서 동작한다.


외부저장소의 공용파일공간이 모두 사라지고 개별앱공간이 샌드박스로 격리되어 제공되며 다른앱이 접근 불가하다

 

MediaStore는 내가 추가한 파일을 읽거나 쓰는데 권한없이 사용 가능하나. 다른앱의 파일을 읽기 위해서는 권한이 필요하다.

 

파일경로(file:///) 만으로 읽고 쓰기가 불가(FileNotFound혹은 권한이 없다는 에러)하다. FileProvider 혹은 시스템 파일 선택기를 통해서 사용자가 직접 파일을 선택한 이후 에야 접근이 가능하다.


Environment.getExternalStorageDirectory()는 deprecated되었다.

 

타앱에 파일을 전달할때 파일경로로 전달불가하며 FileProvider로 ContentUri를 만들고 공유 받을 앱에 임시로 URI접근권한을 허용하는 방법을 사용한다(이전 포스팅 참조)

 

공용저장공간은 /sdcard자체가 공용공간이었으나 이제는 MediaStore와 StorageAccessFramework를 이용하여 공용저장공간에 읽고 쓸수 있다. 이제 이 영역만이 외부저장소라고 할수 있다.

 

사진, 동영상, 음악파일은 MediaStore를 통해 접근이 이미 가능했고 추가로 Download에 저장된 파일에 접근하기 위한 콜렉션을 제공한다. Download도 내가 생성한 파일을 제외하고는 사용자가 시스템파일선택기를 통해 사용자가 명시적으로 선택한 경우에만 접근이 가능하다.

 

파일접근 정리

파일위치 권한 접근 앱삭제시 제거
개별앱 공간 필요없음 getExternalFileDir() Y
미디어콜랙션(사진,비디오,오디오) 다른앱파일접근시만 읽기권한필요 MediaStore or SAF N
다운로드 필요없음 SAF N

느끼고 있겠지만 많은 앱개발자들은 이전 방식을 더 선호한다. 보안에 민감한 클라이언트들은 안그러겠지만...

어쨌든 이전방식을 아직은 사용가능하다.

 

AndroidManifest.xml의 application tag에 requestLegacyExternalStorage플래그를 true로 하면 임시로 이전 저장소정책을 사용할수 있다. 하지만 Target을 Android11로 하면 이 플래그도 지원하지 않을 것이라고 한다.

 

<!-- 임시로 Q(10)에서 opt-out함 -->
<uses-sdk android:targetSdkVersion="29" />
<application android:requestLegacyExternalStorage="true" ... >

문제는 참조하는 다른 라이브러리들이 대응이 안된 경우이다. 별수 없이 해당 라이브러리에서 대응이 되어야 한다.

코드내에서 정책을 확인하기 위해서 isExternalStorageLegacy()를 제공한다.

// storage mode 체크
if (Envirioment.isExternalStorageLegacy()) {
...
}

경우에 따라서는 isExternalStorageLegacy()로 분기하여 파일접근하는 로직을 구분하여 적용해야 할수도 있을것 같다.

Posted by 삼스