본문 바로가기
네트워크

[브라우저에 URL 입력 후 일어나는 일들] 5_TLS/SSL Handshake

by 이농이능 2019. 1. 22.


이전에도 계속 언급했듯 HTTPS 는 HTTP에서 통신 내용을 암호화하는 것이 추가되었습니다. 이때 암호화를 하기 위해 어떤 과정이 일어나는지 알아보도록 하겠습니다.




HTTPS는 클라이언트와 서버간의 통신을 제 3자가 인증을 해주어야 합니다. 이러한 일을 해주는 공인된 회사들을 CA(certificate Authority)라고 합니다. 이러한 CA는 SSL 인증서를 기준으로 클라이언트가 접속한 서버가 맞는지 확인해줍니다. 


SSL 인증서는 클라이언트와 서버간의 통신을 제3자가 보증해주는 전자화된 문서입니다. 인증서를 통해 클라이언트가 접속한 서버가 신뢰할 수 있는 서버인지 판단하고 SSL 통신에 사용될 공개키를 클라이언트에게 전달하는 것입니다. 


SSL 인증서로 서버가 신뢰할 수 있는지 판단하기 위해서 공개키 서명 방식을 사용하는데 이때 방식을 SSL/TLS Handshake 라고 합니다.



SSL/TLS Handshake 란?



암호화 통신은 일반적으로 TLS/SSL 프로토콜을 사용하여 이루어지는데 TLS/SSL 암호화 과정에서 필요한 정보(사용할 암호화 알고리즘, 키) 의 교환을 위한 TLS Handshake 과정이 존재합니다. 해당 과정을 통하여 세션을 생성할 수 있고 이 후 두 노드의 통신은 세션 상에서 수행됩니다. SSL/TLS handshake를 사용하면 SSL 또는 TLS 클라이언트 및 서버가 통신하는 보안 키를 설정할 수 있습니다. 


SSL(Secure Sockets Layer)은 Certificate Authority(CA)라 불리는 서드 파티로부터 서버와 클라이언트 인증을 하는데 사용됩니다. 주로 전송계층과 응용계층 사이에서 보안조치를 하는 데 사용합니다. HTTPS:// 는 SSL을 사용하는 경우를 의미하는 것이죠.

TLS(Transport Layer Security) 로 최근에 부르는데 SSL은 과거 명칭이라서 같은 말입니다.


모든 SSL/TLS 연결은 "Handshake" 과정을 거쳐야 합니다. handshake 과정은 통신을 암호화하는 데 사용할 암호화 알고리즘과 키를 결정하고 서버를 확인하며 실제 데이터 전송을 시작하기 전에 보안 연결이 이루어 졌는지 확인합니다. 이 연결을 확인하기 위한 과정때문에 handshake라고도 하죠.



< SSL/TLS 클라이언트와 서버가 통신하는 단계 >

1. 사용할 프로토콜 버전에 동의.

2. 암호화 알고리즘 선택.

3. 디지털 인증서 교환하고 유효성 검사하여 서로 인증.

4. 비대칭 암호화 기술을 사용하여 공유 비밀키를 생성. 그런 다음 SSL 또는 TLS는 공유키를 사용하여 메세지를 대칭 암호화 방식으로 암호화.



이 과정을 이해하기 위해 먼저 대칭 암호화와 비대칭 암호화인 공개키 암호화에 대해서 알아보도록 하겠습니다.



대칭키 암호화 vs 공개키 암호화(비대칭 암호화) 


- 대칭키 암호화




대칭키 암호란 암호화에 사용되는 키와 복호화에 사용되는 키가 동일한 기법입니다. 그렇기 때문에 암호화한 정보를 보낼 때 암호키를 같이 보내야 해서 타인에게 노출되는 경우 보안에 취약해지는 단점을 가지고 있죠.

키 전달 및 관리에 어려움이 있지만 대칭키 암호화는 연산 속도가 빠르다는 장점도 가지고 있습니다.




-공개키 암호화(비대칭키 암호화)


대칭키가 가지는 해킹의 위험을 막고자 나온 것이 바로 공개키(Public Key)인데요.  암호화와 복호화에 사용하는 키를 분리하는 방식입니다.



공개키 암호화는 비밀키 하나만 가지는 대칭 암호화 방식과 다르게 공개키와 비밀키 두 개가 존재합니다. 

누구에게나 공개 가능한 공개키, 자신만이 갖고 있는 개인키


1.     공개키로 암호화 하는 경우

상대방의 공개키로 데이터를 암호화하고 전달하면 데이터를 전달받은 사람은 자신의 개인키로 데이터 복호화합니다.

2.     개인키로 암호화 하는 경우

개인키의 소유자가 개인키의 데이터를 암호화하고 공개키와 함께 전달합니다. 이 과정에서 공개키와 데이터를 획득한 사람은 공개키를 이용해서 복호화를 하는 것이죠. 데이터 보호의 목적보다는 공개키가 데이터 제공자의 신원 보장하기 위함입니다.

암호화된 데이터가 공개키로 복호화된다는 것은 공개키와 쌍을 이루는 개인키에 의하여 암호화되었다는 것을 뜻합니다. 즉 데이터의 제공자의 신원 확인

이 보장된다는 뜻이기 때문에 전자서명에 이용합니다.





TLS/SSL handshake 방식에서 사용하는 암호화


'handshake' 그 자체는 비대칭 암호화를 사용합니다. 공개키와 개인키도 각각 별도로 사용됩니다. 비대칭 암호화 시스템은 높은 오버헤드를 가지고 있기 때문에 모든 보안 과정을 제공하는 데 사용할 수 없습니다. 그래서 공개키는 handshake 하는 동안 암호 해독을 위한 암호화 및 개인키로 사용되며 서버와 클라이언트가 각각 새로 생성한 공유키를 설정하고 교환하게 합니다.

세션 자체는 공유키를 사용하여 대칭 암호화를 수행하기 때문에 실제 연결에서 오버 헤드를 줄여줍니다.



HTTPS 는 HTTP가 보안에 취약한 것을 보완하는 것으로써 ‘SSL 인증서사용합니다.

클라이언트와 서버간의 HTTPS 통신에 사용되는 전자 문서로 클라이언트는 서버에 접속한 직후 서버로부터 이 인증서를 내려받아 검증합니다. 서버를 신뢰할 수 있는지 판단한 후 통신 이어갑니다.

인증서에는 서버의 공개키가 담기는데 이 인증서는 CA의 개인키로 암호화됩니다.

브라우저 모든 CA들의 공개키 가지고 있어서 인증서를 복호화하고 내용을 볼 수 있습니다


정리해보자면,

1) 인증서에 들어있는 서버의 공개키는 공개키 방식.

2) 서버/클라이언트 양측 모두 pre master secret를 가지고 이 값은 master secret으로 변환되어 최종적으로 session key가 만들어짐. 서버와 클라이언트는 실제 데이터 전송 시 이 session key를 사용해서 암호화/복호화를 함. (대칭키)



TLS/SSL handshake 과정






1. SSL / TLS 클라이언트 컴퓨터가 자신의 버전, 암호 알고리즘 목록, 그리고 사용 가능한 압축 방식을 "client hello" 메시지에 담아 서버로 보냅니다.


2. SSL / TLS 서버는 클라이언트가 제공한 목록에서 서버가 선택한 암호 알고리즘, 선택한 압축 방식과 세션 ID 및 CA(Certificate Authority)가 사인한 서버의 공개 인증서를 "server hello" 메시지에 담아 응답합니다. 이 인증서는 대칭키가 생성되기 전까지 클라이언트가 나머지 handshake 과정을 암호화하는 데에 쓸 공개키를 담고 있습니다.


3. SSL / TLS 클라이언트는 서버의 디지털 인증서가 유효한지 신뢰할 수 있는 CA 목록을 통해 확인합니다. 


4. 만약 CA를 통해 신뢰성이 확보되면 클라이언트는 의사 난수(pseudo-random) 바이트를 생성해 서버의 공개키로 암호화합니다. 이 난수 바이트는 대칭키를 정하는 데에 사용되며 이 대칭키는 나중에 메시지 데이터를 암호화하는 데 사용됩니다.


5. SSL / TLS 서버가 "클라이언트 인증서 요청"을 보낸 경우 클라이언트는 클라이언트의 디지털 인증서 또는 "디지털 인증서 없음 경고" 와 함께 클라이언트의 개인 키로 암호화 된 임의의 바이트 문자열을 보냅니다. 이 경고는 경고일 뿐이지만 일부 구현에서 클라이언트 인증이 필수일 경우 handshake 실패합니다.


6. 서버는 클라이언트의 인증서를 확인합니다. 난수 바이트를 자기 개인키로 복호화해 대칭 마스터키 생성에 활용합니다. 

 

7. 클라이언트는 handshake의 클라이언트 부분이 완료되었음을 알리는 Finished 메시지를 서버에 보내면서 지금까지의 교환 내역을 해시한 값을 대칭키로 암호화하여 담습니다.


8. 서버는 스스로도 해시를 생성해 클라이언트에서 도착한 값과 일치하는지 봅니다. 일치하면 서버도 마찬가지로 대칭키를 통해 암호화한 Finished 메시지를 클라이언트에게 보냅니다.


9. 이후부터 SSL / TLS 세션 동안 서버와 클라이언트는 대칭키로 암호화된 어플리케이션(HTTP) 데이터를 주고 받을 수 있습니다.






다음에는 HTTP 프로토콜을 사용하여 데이터를 주고받는 과정에 대해서 설명하겠습니다 :)