TLS handshake

hi2li·4일 전
  • 한 번 확실하게 개념을 잡아야할 것 같아서 세부적으로 다뤄보았다.

HTTPS 전체흐름

  1. TCP 연결 (3-way handshake)
  2. TLS 핸드셰이크 → 인증서 보내주고, 검증하는 과정 포함
  3. 암호화된 HTTP 통신 (HTTPS통신)
  • TLS핸드셰이크란? : 통신을 하는 클라이언트와 서버가 서로 암호화 통신을 시작할 수 있도록 신분을 확인하고 필요한 정보를 주고 받는 과정.

TLS핸드셰이크 과정(TLS1.2 기준)

Client Hello

  • 클라이언트가 서버에 해당 패킷을 전송한다
  • 해당 패킷으로 TLS 핸드셰이크가 시작된다.
  • 아래 내용들을 포함한다.
    • 클라이언트가 사용가능한 TLS버전
    • 해당 버전에서 지원되는 암호화 방식들(Cipher suites)
    • 클라이언트 무작위라고 불리는 바이트 문자열(Client Random) → 이후 세션키 생성에 사용됨, 세션 ID, SNI등을 포함한다.

Server Hello

  • 클라이언트에게 받은 Client Hello 패킷에 응답이다. → “이걸로 통신하자”를 확정하는 단계
  • 서버는 클라이언트 Hello패킷에 들어있었던 클라이언트가 지원하는 암호화 방식들 중 선택된 방식을 결정하고 보낸다
  • 추가적으로 ‘서버 무작위’(server random)라고 불리는 무작위 바이트 문자열을 포함한 메시지를 클라이언트에게 전송한다. → 이는 추후에 동일한 클라이언트와 동일한 세션키를 만드는 데 사용된다. 최종 세션키 = client Random + server Random + 비밀값(Pre-Master secret이나 shared secret등 암호화 방식에 따라 다르지만 세션키를 만드는데 사용) 이값들을 사용하여 암호학적 함수에 넣어서 세션키를 생성한다.
  • 또 세션 ID를 통해 재연결 세션인지, 새로운 세션인지 확인한다.

Certificate

  • 서버가 자신의 SSL 인증서를 클라이언트에게 전송한다.
  • 인증서 내부에는 서버가 갖고있는 공개 키가 들어있다.
    • RSA방식을 사용하게 되면 클라이언트가 서버에게 Pre-Master Secret을 전달할 때 사용되고
    • ECDHE에서는 클라이언트가 이후에 있을 ServerkeyExchange의 임시공개키 서명을 검증하는데 사용된다.
  • 이후 클라이언트는 CA의 개인키로 서명된인증서를 CA의 공개키를 사용하여 검증한다.
  • 이를 통해 신뢰할 수 있는 웹사이트인지 판단할 수 있다.

Server Key Exchange

  • 키 교환에 필요한 추가 정보를 보내는 메시지
  • RSA방식을 사용하기로 결정할 때는 서버 인증서 안에 이미 공개키가 들어있음
  • 이때는 해당 메시지가 필요없지만 ECDHE, DHE같은 경우에는 임시 키(ephemeral key)를 사용해야한다.
  • 인증서에 없기 때문에 따로 보내줘야 한다.
    • ECDHE같은 경우에는 서버의 EPHMERAL(임시) 공개키, elliptic curve정보, 파라미터, 서명등등
    • 임시키는 Forward securecy라고 나중에 서버키가 털려도 과거 통신을 복호화하지못하게 하기위해 필요하다) → 매 연결마다 새로운 키를 만들기 위해
    • 나중에 세션키 만들 때 = 클라이언트 랜덤 + 서버 랜덤 + 임시키를 사용하여 만든 공유 비밀이렇게 사용한다.
    • 이 임시키도 결국에 서명을 해야하기 때문에 이때는 서버의 개인키로 서명한다.

Server Hello Done

  • 단순 상태 전환 메시지
  • “나 이제 끝났으니까 너차례임”

clientKeyExchange

  • 세션 키를 만들기 위한 secret 을 전달하는 단계
  • RSA방식을 채택했냐, ECDHE를 선택했느냐에 따라 다름
  • RSA방식의경우 클라이언트만 가지고있던 Pre-Master Secret을 보내서 서버도 세션키를 생성할 수 있게 한다.
  • 이때 서버의 공개키(서버에게 받은 인증서안에있음)로 암호화 해서 보내며 서버는 이를 본인의 개인키로 복호화해서 안전하게 받을 수 있다.
  • ECDHE방식에서는 공개키가 없기 때문에 임시키를 보내어 서버와 동일한 세션키를 생성할 수 있도록 한다.
  • 이 단계가 끝나면 클라이언트와 서버는 세션키를 생성한다.
    • client Random
    • server Random
    • Secret(Pre-Master or shared)

ChangeCipherSpec

  • 이제부터 암호화해서 보낸다는 신호
  • 상태전환 메시지

Finished

  • 핸드셰이크 전체가 정상인지 검증하는 메시지
  • 진짜 서버와 클라이언트가 같은 키를 만들었는지
  • 중간에 누가 메시지를 바꾸지 않았는지 확인한느 단계

좋아, 그럼 내가 만든 세션키로 실제로 암호화해서 확인 메시지 보낼게

만약 너가 이걸 풀 수 있으면 우리가 같은 키를 가진거야.

  • 해당 메시지 안에는 verify_data라는 것이 들어간다
  • 지금까지 핸드셰이크했던 모든 정보들을 모아 해시값을 생성한다. 이게 다른거면 누군가가 변조한것.

TLS 1.2와 TLS 1.3

TLS 1.2

image.png

TLS 1.3

image.png

  • TLS 1.3에서는 키교환 단계가 따로 있는 것이 아니라 client hello, server hello단계에서 함께 진행한다.

비교

👉 TLS 1.2

➡️ ClientHello 이후 여러 메시지를 통해 키 교환을 수행하고, 약 2~3 RTT 후 암호화 통신이 시작된다

👉 TLS 1.3

➡️ ClientHello에 키 교환 정보를 포함하여 1 RTT 내에 핸드셰이크를 완료하고, ServerHello 이후 즉시 암호화 통신이 시작된다

profile
갈망하자

0개의 댓글