본문 바로가기
일반IT/IT보안

클라이언트와 서버의 TLS 버전이 달라도 괜찮을까? 🤔 mTLS 통신의 비밀

by gasbugs 2025. 11. 4.

개발을 하다 보면 클라이언트와 서버의 환경이 달라 TLS(Transport Layer Security) 버전이 맞지 않을까 걱정될 때가 있습니다. 특히 상호 인증을 통해 더욱 강력한 보안을 구축하는 mTLS(Mutual TLS) 환경에서, 이 작은 버전 차이가 통신 전체를 실패하게 만들까 봐 불안해지기도 하죠.

 

과연 클라이언트와 서버가 선호하는 TLS 버전이 다르면 mTLS 통신은 불가능할까요?

✅ 결론부터 말하면, 괜찮습니다! (단, 조건이 있어요)

클라이언트와 서버가 서로 다른 버전의 TLS를 선호하더라도, 둘 사이에 공통으로 지원하는 TLS 버전이 하나라도 있다면 문제없이 통신할 수 있습니다. 시스템은 자동으로 그 공통 버전을 찾아내 통신을 시작하고, 그 기반 위에서 mTLS 인증을 수행하게 됩니다.


🤝 마법의 과정, TLS 버전 협상 (Version Negotiation)

이것이 어떻게 가능한지 이해하려면, 모든 TLS 통신의 첫 관문인 'TLS 핸드셰이크(Handshake)' 과정을 알아야 합니다. 이 과정에서 클라이언트와 서버는 마치 첫 만남에서 인사를 나누듯, 어떤 암호화 방식과 '언어(TLS 버전)'로 대화할지 결정합니다. 이것을 '버전 협상(Version Negotiation)'이라고 부릅니다.

전체적인 흐름은 다음과 같습니다.

  1. 🙋‍♂️ ClientHello: 클라이언트의 자기소개 클라이언트가 서버에 접속하면서 "안녕하세요! 저는 이런 기술들을 쓸 수 있어요."라고 말하는 단계입니다. 이때 자신이 지원하는 TLS 버전 목록을 선호하는 높은 버전부터 차례대로 서버에 전달합니다.
    • 클라이언트 ➡️ 서버: "저는 TLS 1.3과 TLS 1.2를 지원합니다. 가능하면 최신 버전인 1.3으로 통신하고 싶어요!"
  2. 🙋‍♀️ ServerHello: 서버의 응답과 결정 서버는 클라이언트가 보낸 목록을 보고, 자신이 지원하는 버전 목록과 비교합니다. 그리고 둘 모두가 지원하는 버전 중 가장 높은 버전을 선택하여 "좋아요! 우리 그 버전으로 대화합시다."라고 응답합니다.
    • 서버 ➡️ 클라이언트: "반갑습니다. 저는 TLS 1.2와 TLS 1.1을 지원하네요. 우리 둘 다 쓸 수 있는 가장 좋은 버전은 TLS 1.2이니, 이걸로 통신을 시작하죠!"
  3. 🤝 통신 시작 이렇게 협상된 TLS 1.2 버전을 기반으로 암호화 통신 채널이 생성됩니다. mTLS에 필요한 클라이언트와 서버 간의 인증서 교환 및 검증 절차는 바로 이 채널 위에서 안전하게 진행됩니다.

💡 mTLS는 언제 등장할까?
mTLS는 독립적인 프로토콜이 아니라, TLS 프로토콜 위에서 동작하는 '인증 강화 옵션'입니다. 따라서, 가장 먼저 기본적인 TLS 핸드셰이크(버전 협상 포함)가 성공적으로 완료되어야만 mTLS 인증 절차를 시작할 수 있습니다. 버전 협상이 mTLS보다 항상 먼저 일어나는 이유입니다.


🎬 실전 예시로 완벽 이해하기!

✅ 통신 성공 시나리오

  • 클라이언트 지원 버전: TLS 1.3, TLS 1.2
  • 서버 지원 버전: TLS 1.2, TLS 1.1
  • 협상 결과:
    1. 클라이언트는 [TLS 1.3, TLS 1.2] 목록을 서버에 보냅니다.
    2. 서버는 자신의 목록 [TLS 1.2, TLS 1.1]과 비교합니다.
    3. 공통으로 지원하는 버전은 TLS 1.2입니다.
    4. 최종적으로 **TLS 1.2**로 통신이 결정되고, 이후 mTLS 인증이 정상적으로 수행됩니다. 🎉

❌ 통신 실패 시나리오

  • 클라이언트 지원 버전: TLS 1.3 (오직 1.3만 지원)
  • 서버 지원 버전: TLS 1.2 (오직 1.2만 지원)
  • 협상 결과:
    1. 클라이언트는 [TLS 1.3] 목록을 서버에 보냅니다.
    2. 서버는 자신의 목록 [TLS 1.2]과 비교합니다.
    3. 공통으로 지원하는 버전이 하나도 없습니다.
    4. 결국 TLS 핸드셰이크가 실패하고 연결이 중단됩니다. mTLS 인증은 시도조차 할 수 없습니다. 😥

👨‍💻 실제 데이터 엿보기: Wireshark로 본 핸드셰이크

실제 네트워크 패킷에서는 이 과정이 어떻게 보일까요? Wireshark와 같은 도구로 캡처한 TLS 핸드셰이크 데이터는 다음과 같습니다.

1. ClientHello 패킷

클라이언트가 자신이 지원하는 버전 목록(supported_versions)을 보내는 것을 볼 수 있습니다.

Transport Layer Security
    TLSv1.3 Record Layer: Handshake Protocol: Client Hello
        Handshake Protocol: Client Hello
            Version: TLS 1.2 (0x0303)
            Extension: supported_versions (len=5)
                Supported Versions Length: 4
                Supported Version: TLS 1.3 (0x0304)
                Supported Version: TLS 1.2 (0x0303)

ℹ️ 위 데이터에서 클라이언트는 TLS 1.3과 1.2를 지원한다고 알리고 있습니다.

2. ServerHello 패킷

서버는 클라이언트의 목록을 보고 자신이 선택한 단 하나의 버전을 응답합니다.

Transport Layer Security
    TLSv1.3 Record Layer: Handshake Protocol: Server Hello
        Handshake Protocol: Server Hello
            Version: TLS 1.2 (0x0303)
            Extension: supported_versions (len=2)
                Supported Version: TLS 1.2 (0x0303)

ℹ️ 서버는 클라이언트가 보낸 목록과 자신의 능력을 고려하여 최종적으로 TLS 1.2를 선택했음을 명확히 알려줍니다.


✨ 핵심 정리: 이것만 기억하세요!

복잡해 보이지만 핵심은 간단합니다.

클라이언트와 서버가 mTLS 통신을 할 때, 각자가 선호하는 TLS 버전이 다른 것은 전혀 문제가 되지 않습니다. 가장 중요한 것은 양측이 공통으로 지원하는 TLS 버전이 단 하나라도 존재하는가 입니다.

 

만약 공통 버전이 있다면, 시스템은 알아서 최적의 버전으로 협상하여 안전한 통신을 시작할 것입니다. 이제 버전 차이에 대한 막연한 불안감은 떨쳐버리고, 시스템의 똑똑한 '협상' 능력을 믿어보세요!