좀 열심히 쓴 글

TLS Handshake

ch4rli3kop 2018. 9. 21. 19:29
반응형
end-to-end 서비스 상에서는 서버와 클라이언트의 인증, 데이터의 기밀성과 무결성을 보장하기 위해, Transport Layer SSL 패킷 안에 Application 데이터를 캡슐화하는 암호화 통신을 사용한다. 암호화 통신은 일반적으로 TLS/SSL protocol을 사용하여 이루어지는데, TLS/SSL 암호화 과정에서 필요한 정보들(사용할 암호화 알고리즘, 키)의 교환을 위한 TLS Handshake 과정이 존재한다. 해당 과정을 통하여 세션을 생성할 수 있고, 이 후 두 노드의 통신은 세션 상에서 수행된다.


IN THEORY



=== Phase 1 ===

①, ②과정에서 client와 server는 각 각 random 값을 생성하여 상대방에게 전송한다. 


이후, client와 server는 SSL의 버전, 키 교환, 메시지 인증과 암호화를 위한 알고리즘, 압축 방법, 키 생성을 위한 2개의 난수를 알게 된다.


=== Phase 2 ===

③과정 직후, ServerKeyExchange 메시지가 송신될 수 있다. RSA나 fixed Diffie-Hellman 방식에서는 certificate에서 공개 캐를 보내기 때문에 ServerKeyExchange과정이 존재하지 않지만, ephermeral Diffie-Hellman 방식이나 Anonymous Diffie-Hellman 방식은에서는 존재한다.



또한, server는 client의 인증을 요구하는 CertificateRequest 메시지를 보낼 수 있다. server가 믿고 있는 상위 CA들의 목록을 포함하고 있다. Anonymous Diffie-Hellman에서는 client에게 인증서를 요구할 수 없다.

④과정에서는 ServerHello가 끝났다라는 것을 알린다.


이후, server는 client에 대해 인증이 되고, client는 server의 공개 키를 알 수 있게 된다.


=== Phase 3 ===

server가 인증서를 요청하였다면 ⑤전에, client 인증서를 Certificate 메시지를 통하여 전송한다. client를 인증하는 인증서 체인을 포함한다. 요청이 있는데 client가 보낼 인증서가 없다면, 인증서가 없다는 경고와 함께, Alert 메시지를 보낸다.

⑤과정에서 client는 pre-master secret을 ClientKeyExchange 메시지를 통해서 server에게 전송한다. 암호화 방식은 server와 합의된 암호 알고리즘(ex. RSA, Diffie-Hellman, Fortezza)을 이용한다.

서버가 클라이언트의 인증서를 요청하였을 경우, 받은 인증서가 실제 client의 인증서가 맞는지 증명하는 작업이 필요하다. ⑤과정 직후에 CertificateVerify 메시지를 server로 전송함으로써 client의 인증서를 검증한다. 

⑤과정에서 client는 pre-master secret(48 bytes)을 생성한뒤, server와 합의된 암호 알고리즘(ex. RSA)을 이용하여 pre-master secret을 전송한다. ⑤과정이 끝나면 client와 자신의 개인 key로 복호화하여 pre-master secret을 얻은 server는 pre-master secret과 client random, server random 값을 SHA-1과 MD5 해쉬 함수를 이용하여 Master secret(48 bytes)를 생성한다.

위의 과정을 이용하여 Master secret을 생성했다면, 이제 이 Master secret과 client random, server random을 이용하여 Key material을 생성한다. 

Key material은 client 및 server가 사용할 암호화 key를 생성한다.




이후, client는 server에 대해 인증되고, client와 server 양측은 pre-master secret을 알게 된다.



=== Phase 4 ===

본 단계에서는 client와 server가 암호 규격을 변경하고 Handshake 프로토콜을 종료하기 위한 메시지를 보낸다.


⑦과정 ChangeCipherSpec은 client와 server가 대기 상태에서 활성 상태로 모든 암호문 집합과 매개변수가 이동된 것을 나타내기 위해 보내는 메시지이다.

ChangeCipherSpec 과정에서는 대기 상태와 활성 상태로 나뉘어질 수 있고, 각 상태는 read(receiving)와 write(sending)의 두 가지 값을 가진다. 대기 상태에서는 매개변수와 secret을 기록해두고, 활성 상태에서는 암호화나 복호화를 위하여 매개변수와 secret 값들을 유지하는 형태이다.
ChangeCipherSpec Protocol을 자세히 살펴보면 다음과 같은 과정이 수행된다. 

ChangeCipherSpec 메시지를 교환하기 전에는 대기 열만 값들을 가지게 되고, client가 ChangeCipherSpec 메시지를 보낸 뒤에, client는 대기에서 활성으로 write 매개변수가 변한다. client는 이제 outbound 메시지를 서명 또는 암호화하는데 해당 매개변수들을 사용할 수 있다. server는 client가 보낸 이 ChangeCipherSpec 메시지를 수신한 뒤에, 대기 상태에서 활성 상태로 read 매개변수가 변한다. 이제 server는 메시지를 복호화하거나 검증할 수 있다.

server가 ChangeCipherSpec 메시지를 보내고 나면, 위와 비슷하게 server의 write 매개변수가 대기상태에서 활성상태로 변하고, client의 read 매개변수가 대기상태에서 활성상태로 변한다.

이제 양 당사자들은 read/write 활성 매개변수를 사용하여 양 방향으로 통신을 할 수 있다.

⑧과정에서는 Finished 메시지가 전송된다. Handshake 과정의 끝을 알리는 메시지이다. Finished 메시지는 서명이나 암호화되어 상대방이 검증하는 용도로 사용될 수 있다.


이후, client와 server는 데이터를 교환할 준비가 된다.






IN PACKET

Display filter에서 ssl.handshake 혹은 ssl.record.content_type == 22를 사용하여 TLS Handshake 관련 세션을 확인할 수 있다.


아래의 그림은 예시로 잡아본 TLS Handshake 과정이다.



Client Hello

먼저 일반적인 HTTPS의 경우 443 포트를 사용하는 것을 확인할 수 있다.


SSl 부분을 보면 Content Type 이 22로 Handshake를 나타내는 것을 알 수 있는데, 아까 사용한 ssl.record.content_type == 22은 이 영역에 대한 값으로 필터링한 것이다.
{20 : change_cipher_spec, 21 : alert, 22 : handshake, 23 : application_data}


Handshake Type 필드의 값 (1)을 통해 해당 패킷이 Client Hello에 관련된 패킷이라는 것을 알 수 있다. 또한, client가 지원할 수 있는 Version 중 가장 높은 것이 TLS 1.2 라는 것을 확인할 수 있다. {0x0300 : SSL 3.0, 0x0301 : SSL/TLS 1.0, 0x0302 : SSL/TLS 1.1, 0x0303 : SSL/TLS 1.2}
Compression(압축) 방식은 선택사항이다. 특정 압축 알고리즘은 SSL version 3에서 정의되지 않았기 때문에, 기본 압축 방법은 NULL이다.


Random 필드에 존재하는 Random Bytes는 Handshake 과정이 끝난 뒤, 세션 키(대칭 키)를 생성하는데에 사용된다. client의 random 값과 server의 random 값 


Client Hello의 Cipher Suites에서는 해당 Client의 브라우저에서 지원할 수 있는 암호화 방식의 목록을 보여준다. 위의 그림에서는 17개의 암호화 방식을 지원함을 나타내고 있다.


위의 그림에서는 TLS Extension 필드들을 확인할 수 있다. Extension 필드는 선택적으로 사용된다. Extension 필드는 매우 다양한 정보들을 가질 수 있는데 필드 중 server_name 필드는 Server의 이름을 포함하고 있다.



Server Hello

server hello의 경우에도 Content Type은 Handshake를 갖는다. 다만, Handshake Type 값을 2로 Server Hello의 값을 갖는다. server hello에서 역시 client hello와 마찬가지로 Version과 Random 값을 확인할 수 있다. Session ID 값이 0일 경우, 새 세션임을 나타낸다. 0이 아니라면 재시작된 세션이다. Cipher Suite는 이전 client가 지원하는 암호화 방식 중 하나를 선택하여 선택된 방식을 client에게 보낸다. 또한, 선택적으로 Extension 필드가 사용될 수 있다.



Certificate

certificate의 Handshake Type은 11이다.


certificate가 4개 존재한다. 가장 하위에 존재하는 것이 ROOT CA에 대한 인증서이고, 가장 위에 존재하는 것이 서버의 인증서이다.

인증서의 시리얼 넘버나 유효기간, 서버의 공개 키 등을 확인할 수 있다.



참고 : 
Cryptography and Network Security. by Behrouz A Forouzan
Wireshakr Network Analysis. by Laura Chappell



반응형