[TIL] 아스키코드와 유니코드, TLS

devAnderson·2022년 5월 10일
0

TIL

목록 보기
95/103

0. 🚍 오늘 배우는 개념들은

pdf를 생성한 Buffer 데이터를 클라이언트에게 보내는 과정 중에 문제가 발생했는데, 이 원인을 분석하기 위해 수많은 지식들을 받아들어야 했으므로 정리를 할 필요가 있어서 쓰는 글이다.

Blob 을 이용해 PDF로 다운로드하는 방법은 아래 링크에 블로깅해두었다

pdf를 달라

1. 🚍 아스키코드와 유니코드

컴퓨터는 기본적으로 전기적 신호로 통신을 한다. 전기가 흐른다면 1, 전기가 흐르지 않는다면 0을 이용하여 두가지 케이스로 정보를 표현하고, 이 0과 1이 들어가는 단위의 조합을 "bit"라고 한다. 그리고 8비트는 1 바이트라고 표현한다.

1 바이트가 8비트이므로, 1바이트는 최대 2^8 케이스인 256가지의 케이스를 표현하는 것이 가능하다. 그렇다면 우리가 사용하는 10mb 와 같은 단위는 얼마나 많은 케이스를 포함하는 것인지 ... 마치 광활한 우주를 보는 듯 하다.

컴퓨터는 오로지 0과 1만 아는 바보이기때문에 우리가 사용하는 "ㄱ,ㄴ,ㄷ" 과 같은 단어를 이해하지 못한다.
이것을 이해시키려면, 미리 표로 등록하여 케이스별로 분류를 해둘 수밖에 없다. 이로 인해 생긴 것이 바로 아스키 코드이다.

아스키 코드는 "영어" 를 표현하기 위한 데이터 표이며 8바이트를 기반으로 작동한다.
(정확히 말하면 7바이트로 데이터를 표현하고, 중간의 한자리를 parity bit라고 비워둔 상태로 에러감지를 하기 위해 사용한다.)

다만 이 아스키 코드는 문제점이 영어만 표현할 수 있기 때문에 세계의 다양한 단어나 이모지 등을 포함하기엔 부족하다. 그래서 생겨난 것이 유니 코드이다.

유니코드 란 아스키 코드를 국제 표준을 위해 데이터화한 테이블이라고 생각하면 편하다.
영어 표현에는 1바이트, 한글은 2바이트, 기타는 3,4바이트를 이용해 표현한다.

다만, 이렇게 가변적인 해석방식 때문에 ( 메모리 상에 저장된 정보를 어디까지 읽어들어야 할지를 명확하게 정할 수가 없음 )
그 기준점을 위한 방식이 필요한데 이것이 바로 "인코딩 방식" 이다.

우리가 친숙하게 볼 수 있는 "UTF-8"은 간단하게 말하자면

아스키 식이 가능하면 아스키식으로, 아니라면 유동적으로 읽어들여라. 8비트(1바이트)마다 기준점으로 인덱싱해서...
라는 인코딩 방식의 지침이다. (뒤의 8이 비트를 의미한다)

이때, 아스키식이 가능한지 안한지를 구분하는 방법은 첫번째 비트가 어떤것인지에 따라 결정된다.
첫번째 비트가 0으로 시작하면 아스키식으로 인코딩해서 불러들이고, 그 외에는 케이스별로 나눈다.

// 예를 들어,

0xxxxxxxx(8비트, 아스키 방식) : 첫자리가 0이므로, 아스키식으로 해석한다
110xxxxx xxxxxxx (16비트, 2바이트까지 읽어들여 해석) ... : 첫자리가 1이고, 두번째가 1이므로 총 16비트인 2바이트를 하나로 묶어서 인코딩해라 

1110xxxx xxxxxxxx xxxxxxxx (24비트, 3바이트까지 읽어들여 해석) .... : 첫자리가 1이고, 세번쨰가지 1이므로 총 24비트인 3바이트를 하나로 묶어서 인코딩해라.

참고로 utf-16, utf-32 등도 있지만, 요즘 대부분의 환경에서의 인코딩 방식으로 utf-8을 사용한다고 한다.
그러나, 가끔 한국식 독자적 인코딩 방식인 EUC-KR 이나, java에서는 utf-16을 사용하는 경우가 많아서 충돌이 나기도 하므로 이럴때는 환경에 따라서 utf-8로 컴파일하여 개발하는 방식이 이용된다고 한다.

2. 🚍 TLS

TLS는 HTTPS 즉, Hypertext Transfer Protocol Secure 을 만들기 위한 절차이다. 공개키와 비공개키를 이용한 대칭, 비대칭 원리를 혼합한 방식을 사용한다.

대칭방식은, 공개키로 암호호화 한 것은 공개키로 해독이 가능하고 비대칭 방식은 공개키로 암호화 한 것은 비공개키로만 해독이 가능한 메커니즘이다.

서버와 HTTPS 통신으로 업그레이드하기 위해서는, 우선 서버가 CA(인증기관)로부터 SSL 인증서를 받으므로 시작된다. (SSL은 TLS의 기존 이름이다)

  1. 서버가 공개키와 비밀키를 생성한다.
  2. CA에 서버의 공개키와 함께 서버정보를 전달한다
  3. CA는 서버 공개키와 서버정보를 압축시킨 후 비밀키와 공개키를 생성한 뒤, 이 압축 내용을 "CA의 비밀키를 이용해 암호화하여 SSL 인증서를 생성한다"
  4. 암호화한 SSL 인증서를 서버에게 전달한다.

이 뒤에는 서버연결을 위한 TCP, 그리고 비대칭 암호키 전달을 위한 TLS가 연달아서 일어난다 (중요!)

참고로 이 부분이 늘 의문이었는데 드디어 해결했다... 속시원하다 정말

TCP는 3 handshake 를 통해서 서버와 클라이언트의 상호 연결을 실행한다. (OSI 7계층에서 4단계인 전송계층을 의미한다)

그리고 나서, (어디에선가는 3.5단계라고 표현하는) TLS 연결이 시작된다.

1. client hello

서버에게 "우리 https 연결을 합시다." 라는 요청을 http요청을 통해 날린다.
이때 전송되는 내용 중 가장 대표적인 것은 어떤 암호방식(Cipher suite)을 사용할것인지 선택할 수 있도록 암호방식 목록의 리스트를 보낸다는 것이다.

2. server hello

서버는 해당 요청에 대해서 어떤 Cipher suite를 이용할지를 선택한 결과를 담아서 응답해준다

3. certificate

server hello는 일단 날려둔 후, 서버는 CA에게서 받아왔던 SSL 인증서를 또 보낸다. 이 안에는 아까 서버가 자신의 공개키와, 서버정보를 압축해놓은 정보가 담겨 있다.

4. client는 서버의 SSL을 검증한다.

이때 이 인증서가 확실한지 검증하는 것은 브라우저 내에 저장 된 신뢰받을 수 있는 CA의 공개키이다. 인증서는 비밀키로 암호화되어 있었기 떄문에 공개키로만 열릴 수 있다.

5. 서버의 공개키로 대칭키 생성

매번 비대칭키로 통신하는 것은 보안에도 좋지 않고 속도도 느리기 때문에 대칭키를 교환하기 위한 절차로 먼저 클라이언트가 pre-master secret이라는 대칭키 데이터를 서버의 공개키로 암호화한 뒤 서버에게 전달한다. (서버의 공개키로 암호화되었기때문에, 서버가 은닉하고 있는 비밀키로만 해독이 가능하다)

6. 서버는 대답을 보낸다

pre-master-secret을 자신의 비밀키로 해독한 서버는 이것을 가지고 대칭키인 master-secret을 만든다. 클라이언트도 역시 이것을 가지고 있으므로 동일하게 master-secret을 만든다.

이렇게 가지고 있는 서로의 대칭키를 이용하여 안전하게 https 커뮤니케이션을 실행한다.

reference

아스키 vs 유니코드

HTTPS

MIME

profile
자라나라 프론트엔드 개발새싹!

0개의 댓글