TLS handshake

hi2li·2026년 4월 5일

security

목록 보기
4/12
  • 한 번 확실하게 개념을 잡아야할 것 같아서 세부적으로 다뤄보았다.

HTTPS 전체흐름

  1. TCP 연결 (3-way handshake)
  2. TLS 핸드셰이크 → 인증서 보내주고, 검증하는 과정 포함x
  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.3

[ client Hello + Key share ]

클라이언트는 서버에게 다음 정보를 보낸다.

  • 지원 TLS 버전

  • Cipher Suite

  • Client Random

  • Key Share (임시 공개키)

    -> TLS 1.2와 달리 키 교환 정보를 처음부터 보내버린다.

[ Server Hello + Finished ]

서버는 다음 정보를 한 번에 응답한다.

  • Server Hello
  • Key Share
  • Certificate
  • Certificate Verify
  • Finished

-> 서버도 자신의 Key share를 보내기 때문에 이 시점에 클라이언트와 서버는 동일한 shared secret를 계산할 수 있다.

  • 이후 이 Shared Secret을 기반으로 양쪽모두 동일한 세션키를 생성한다.

따라서 1RTT 만에 암호화 통신을 시작할 수 있다.

[ Client Finished ]

클라이언트는 마지막 확인 메시지인 Client Finished를 전송한다.

  • 이 메시지는 최종 검증용이며, 이미 전부터 암호화 통신은 가능하다.






TLS 1.2 VS TLS 1.3

[ 1. 핸드셰이크 속도 ]

TLS 1.2

  • Server Key Exchange, Client Key Exchange 등의 별도 단계가 존재
  • ChangeCipherSpec 메시지를 클라이언트와 서버가 각각 전송
  • 암호화 통신 시작까지 약 2 RTT (TCP 포함 시 약 3 RTT)

TLS 1.3

  • Key Share를 ClientHello와 ServerHello 단계에서 교환
  • 불필요한 메시지 제거
  • 대부분의 경우 1 RTT 만에 암호화 통신 시작 가능

[ 2. 키 교환 방식 ]

TLS 1.2

  • RSA, DHE, ECDHE 등 다양한 방식 지원
  • 일부 환경에서는 Perfect Forward Secrecy(PFS)가 적용되지 않을 수 있음

TLS 1.3

  • ECDHE 기반 키 교환 사용
  • 모든 연결에서 Perfect Forward Secrecy(PFS) 기본 적용

[ 3. 보안성 ]

TLS 1.2

  • 오래된 암호화 알고리즘 사용 가능
  • 보안 설정에 따라 취약한 구성이 남아 있을 수 있음

TLS 1.3

  • 취약하거나 오래된 암호화 알고리즘 제거
  • 더 단순하고 안전한 암호화 스위트만 사용

[ 4. 세션 재개 ]

TLS 1.2

  • 세션 재개 시에도 최소 1 RTT 필요

TLS 1.3

  • 선택적으로 0-RTT 지원
  • 이전에 연결했던 서버와 더 빠르게 통신 가능

profile
Easy come , Easy go

0개의 댓글