0 / 9
TLS 1.2 핸드셰이크(TLS 1.2 Handshake)
TLS(Transport Layer Security, 전송 계층 보안)는 브라우저와 웹 서버처럼 처음 만난 두 쪽이 안전하게 통신하게 해 주는 프로토콜이다. 데이터를 주고받기 전에 두 쪽은 먼저 핸드셰이크라는 메시지 교환을 한다. 여기서 암호화 방식을 정하고, 서버가 진짜인지 확인하고, 같이 쓸 키를 만든다. 이 그림은 그 순서를 TLS 1.2 기준으로 보여 준다. 크게 협상, 서버 인증, 키 교환, 완료 확인의 네 덩어리다. 핸드셰이크가 끝나면 암호화된 통신이 시작된다.
예: 브라우저(Client)가 쇼핑몰 웹서버(Server)에 처음 접속한다.
1 / 9
Client → Server: ClientHello
Client가 먼저 말을 건다. 자기가 지원하는 가장 높은 TLS 버전과 쓸 수 있는 암호 스위트 목록, 그리고 무작위 값(난수) Client Random을 보낸다. 난수는 비밀이 아니라 그대로 오가는 값이고, 연결마다 키가 달라지게 하는 데 쓴다. 암호 스위트는 키 교환·인증·암호화에 쓸 알고리즘을 한 세트로 묶은 것이다.
2 / 9
Server → Client: ServerHello
Server가 Client의 목록에서 둘 다 쓸 수 있는 암호 스위트를 하나 고르고 TLS 버전도 정해서 알려 준다. 자기 난수 Server Random도 함께 보낸다. 여기까지가 협상이다.
3 / 9
Server → Client: Certificate
Server가 자기 인증서를 보낸다. 인증서에는 Server의 공개키와, 이 키가 해당 도메인의 것이라는 인증 기관(CA)의 서명이 들어 있다. ServerHelloDone도 같이 보내서 hello 단계의 메시지가 여기서 끝났다고 알린다.
4 / 9
Client: 인증서 검증
Client가 인증서를 직접 검사한다. 인증서의 서명을 중간 CA를 거쳐 브라우저에 미리 들어 있는 루트 CA까지 따라가며 맞는지, 유효기간이 지나지 않았는지, 접속한 도메인과 인증서의 도메인이 같은지 본다. 인증서가 폐지되지 않았는지도 CRL이나 OCSP로 확인할 수 있다. 하나라도 틀리면 경고를 띄우거나 연결을 멈춘다. 모두 맞으면 이 공개키를 진짜 Server의 것으로 믿는다.
5 / 9
Client → Server: ClientKeyExchange
Client가 세션 키(이 연결에서만 쓰는 대칭키)의 재료가 될 비밀 값 Premaster secret을 만든다. 이 값을 Server의 공개키로 암호화해 보낸다. 중간에서 가로채도 Server의 개인키가 없으면 풀 수 없다.
6 / 9
Client와 Server: 세션 키 계산
Server가 자기 개인키로 Premaster secret을 푼다. 이제 두 쪽 다 Client Random, Server Random, Premaster secret을 갖고 있다. 각자 같은 계산을 한다. 세 값으로 마스터 시크릿(master secret)을 만들고, 거기서 실제 암호화에 쓸 키를 뽑는다. 그래서 두 쪽이 같은 세션 키를 갖게 되고, 세션 키 자체는 네트워크로 보내지 않는다.
7 / 9
Client → Server: ChangeCipherSpec, Finished
Client가 ChangeCipherSpec으로 지금부터 세션 키로 암호화해서 보내겠다고 알린다. 바로 이어 Finished를 보낸다. Finished에는 지금까지 주고받은 핸드셰이크 메시지 전체의 검증값이 들어 있고, 세션 키로 암호화한 첫 메시지이기도 하다.
8 / 9
Server → Client: ChangeCipherSpec, Finished
Server도 ChangeCipherSpec과 Finished를 같은 방식으로 보낸다. 받은 검증값이 자기가 계산한 값과 같으면 협상 내용이 중간에 바뀌지 않았고 같은 세션 키를 가졌다는 뜻이다. 올바른 Finished를 만들려면 Premaster secret을 풀 수 있어야 하니, 개인키를 가진 진짜 Server라는 마지막 확인도 된다. 맞지 않으면 연결을 끊는다.
9 / 9
암호화된 통신 시작
핸드셰이크가 끝났다. 이제부터 오가는 데이터(Application Data)는 세션 키로 암호화한다. 암호화와 복호화에 같은 키를 쓰는 대칭키 방식이라 빠르다. 느린 공개키 암호는 데이터에는 쓰지 않고 키를 정할 때만 쓴다.