암호화 알고리즘

TLS/SSL 통신 - 1 (공개키 알고리즘 Usecase)

skyjumbo 2023. 10. 11. 17:51

TLS/SSL 프로토콜은 월드 와이드 웹의 보안을 위해 개발된 것입니다. 초기 인터넷 통신은 평문으로 이루어졌기 때문에 암호화되지 않았고, 개인 정보나 기밀 정보 등이 노출될 가능성이 매우 높았습니다. 이러한 문제를 해결하기 위해 SSL(Secure Socket Layer)이라는 프로토콜이 등장했고, 이후 TLS(Transport Layer Security)로 대체되었습니다. TLS/SSL는 인터넷 상에서 데이터를 보호하기 위한 프로토콜로, 서버와 클라이언트 간의 통신을 암호화하고 인증하는 기능을 제공합니다.

TLS/SSL는 웹 브라우저와 웹 서버 간의 통신에 가장 많이 사용되며, HTTPS(Hypertext Transfer Protocol Secure)라는 프로토콜을 통해 구현됩니다. HTTPS는 HTTP 프로토콜의 보안 버전으로, TLS/SSL 프로토콜을 사용하여 데이터를 암호화하고 인증합니다.

SSL(Secure Sockets Layer)와 TLS(Transport Security Layer)는 SSL/TLS 라고 같이 표기하는데, 이는 버전업 되면서 SSL → TLS로 이름이 변경된 것입니다. 다만 TLS 로 이름이 바뀌면서 서로 호환이 되지 않기 때문에 SSL/TLS 로 표기합니다. 각 버전은 다음과 같습니다.

  • SSL 2.0 (1995)
  • SSL 3.0 (1996)
  • TLS 1.0 (1999)
  • TLS 1.1 (2006)
  • TLS 1.2 (2008)
  • TLS 1.3 (2018)

2022년 기준으로 보면 다음과 같습니다.

  • SSL ~ TLS 1.1: 보안 문제로 사용 금지되었습니다
  • TLS 1.2: 현재 가장 많이 사용합니다
  • TLS 1.3: 주요 브라우저에서 지원됩니다

TLS의 암호화 방식

TLS에서는 대칭키와 공개키 암호화 방식을 함께 사용합니다. 대칭키 암호화 방식은 암호화와 복호화에 같은 키를 사용하는 방식으로, 빠르고 간단하게 데이터를 암호화할 수 있지만, 키를 안전하게 전달해야하는 문제가 있습니다. 공개키 암호화 방식은 암호화와 복호화에 사용하는 키가 다른 방식으로, 키를 안전하게 전달하지 않아도 되는 장점이 있습니다. 실제 TLS 암호화 방식은 다음과 같이 정리될 수 있습니다.

  1. 처음에 대칭키를 서로 공유하기 위해 RSA 비대칭키 방식을 이용합니다.
  2. 실제 통신을 할 때는 공유한 대칭키를 사용하여 데이터를 주고 받습니다

TLS 암호화 방식 (출처: https://babbab2.tistory.com/4)

Alice와 Bob이 통신을 하는 경우, Alice와 Bob은 각자 공개키와 개인키(비밀키)를 가지고 있습니다. 이 때, Alice와 Bob이 서로 대칭키를 공유하고자 할 때, 다음과 같은 과정을 거칩니다.

  1. Alice은 자신의 공개키(1111)를 Bob에게 전송합니다.
  2. Bob은 Alice의 공개키로 대칭키(1234)를 암호화하여(RSA 알고리즘) Alice에게 전송합니다.
  3. Alice은 자신의 개인키(qqqq)로 암호화된 대칭키를 복호화하여 사용합니다.

이 과정에서, 대칭키를 전달하는 과정에서는 Alice의 공개키를 사용하여 대칭키를 암호화했기 때문에 안전하게 전달됩니다. 대칭키를 이용하여 데이터를 암호화하고 복호화할 수 있기 때문에, Alice와 Bob은 이제 안전하게 대칭키를 공유하고 데이터를 주고받을 수 있습니다.


TLS 통신

본격적인 TLS 통신을 위해 클라이언트와 서버는 다음과 같은 단계를 거치게 됩니다:

  1. TLS 핸드쉐이크 (비대칭키 사용해서 대칭키 생성)
  2. 데이터 전송 (대칭키로 데이터 암호화)
  3. TLS 종료 (사용된 대칭키 폐기)

현재 모든 대부분의 TLS 통신에선, TLS 1.2가 사용되지만 대부분의 서버는 더 좋은 성능과 보안성 때문에 비교적 최근에 개발된 TLS 1.3으로 전환되고 있습니다. 두 버전은 지원되는 암호화 알고리즘이 크게 다른것 외에도 초기 클라이언트와 서버간 연동을 시작하는 핸드쉐이크 과정에서 크게 차이가 발생합니다. 아래는 TLS 통신 패킷 분석 프로그램 WireShark을 통해 분석되었습니다.

TLS 1.2 핸드쉐이크

TLS 핸드쉐이크는 SSL/TLS 프로토콜에서 사용되는 핸드쉐이크 과정을 의미합니다. TLS 핸드쉐이크는 SSL/TLS 연결을 설정하고 서버와 클라이언트 간에 인증서 교환 및 암호화 방식을 협상하는 데 사용됩니다. TLS 핸드쉐이크는 TLS 프로토콜 버전에 따라 다양한 단계로 이루어질 수 있지만, 대개는 클라이언트가 서버에 접속 요청을 보내면 서버가 인증서를 보내고 클라이언트가 이를 검증한 후, 서로의 지원하는 암호화 방식을 협상하고, 세션 키를 교환하는 과정을 거칩니다. 다음 그림을 통해 세부 과정을 살펴보겠습니다:

TLS 1.2 (출처: https://www.thesslstore.com/blog/explaining-ssl-handshake/)

① Client Hello (Client) 

클라이언트는 서버에 접속해서 Client Hello의 패킷을 전송합니다. 해당 패킷에는 다음이 전송됩니다:

1. Version: 클라이언트에 사용되는 TLS version을 표기합니다.

2. Cipher Suite List: 클라이언트가 지원하는 암호화 방식으로, 클라이언트와 서버가 어떤 암호화 방식을 사용할 것인지 정하며, 대칭키, 비대칭키 암호화 알고리즘과 해시함수를 정합니다.

3. Client Random Data: 클라이언트는 CSPRNG 난수 알고리즘으로 256-bit의 난수를 생성하여, 나중에 서버와 공유할 대칭키를 만들 때 사용됩니다.

4. Session ID: TLS 통신에서 Handshake를 하는 과정은 긴 시간이 소요되며 모든 연결마다 핸드쉐이크를 하는 것은 비효율적이기 때문에, 최초의 핸드쉐이크만 Full Handshake을 진행하며, 이후에는 저장된 session ID로 간소화된 핸드쉐이크를 진행합니다. 시간 상 약 100ms가 절약되며, Session ID = 0 일 때 Full Handshake가 진행됩니다.

5. SNI(Server Name Indication): 서버의 이름을 표시하는 부분으로, IP 주소에 접속할 때, 어떤 도메인에 접속하는 지 명시하는 부분입니다. SNI 를 이용하면 물리적으로 동일한 서버에 존재하는 각기 다른 도메인들이 서로 다른 TLS 인증서를 적용할 수 있습니다.

② Server Hello (Server) 

클라이언트가 보낸 Client Hello에 대해 서버에서 응답하며, 전송되는 패킷은 다음과 같습니다:

1. TLS version: 서버에서 사용되는 TLS version입니다.

2. Selected Suite:  Client가 보낸 암호화 방식 중에 서버가 사용 가능한 암호화 방식을 선택하여 보냅니다. 주로 사용되는 방식은 TLS_ECDHE_RSA_WITH_ASE_128_GCM_SHA256입니다. 이를 자세하게 살펴보면 다음과 같습니다.

-TLS_ECDHE_RSA: 암호 조합에서 사용되는 키 교환 알고리즘을 나타냅니다. 이 경우, ECDHE (타원 곡선 디피-헬만 에페머럴)를 사용하여 키 교환을 수행하며, RSA는 디지털 서명에 사용됩니다.

-WITH_AES_128_GCM_SHA256: 암호화 및 메시지 인증 알고리즘을 나타냅니다. 이 경우, AES (고급 암호화 표준) 128비트 길이의 GCM (갈루아/카운터 모드)을 사용하여 암호화하고, SHA256 (안전한 해시 알고리즘 256)을 사용하여 메시지 인증을 수행합니다.

3. Server Random Data: 서버에서 생성한 난수로, 클라이언트와 동일하게 대칭키를 만들 때 사용합니다.

4. Session ID: Client Hello에 Session ID가 0으로 왔다면 새로 Session ID를 생성해 보내며, Session ID가 0이 아니라면 유효한 Session ID인지 검증하고 보냅니다.

5. SNI(Server Name Indication): 클라이언트와 다르게 SNI를 0으로 비워서 보냅니다.

③ Certificate (Server) &  ④ Server Key Exchange (Server) & ⑤ Server Hello Done (Server)

서버의 인증서를 클라이언트에게 보내는 단계로, 필요에 따라 CA의 Certificate도 함께 전송됩니다. 클라이언트는 이 메세지를 통해 서버의 인증서가 무결한지 검증합니다. 서버의 인증서에 대한 검증이 유효한 경우, 이전에 주고 받았던 클라이언트의 난수와 서버의 난수를 조합하여 pre master secret 이라는 대칭키를 생성합니다. 이후 생성된 대칭키를 클라이언트에 전송을 합니다. 성공적으로 클라이언트에 전송이 완료되면 아래와 같이 하나의 패킷으로 묶여서 모든 과정을 표시합니다.

클라이언트는 서버에서 전송되는 인증서가 유효한지 검증을합니다. 이 인증서를 이용해서 클라이언트는 서버가 믿을 만한, 신뢰할 만한 서버인지 확인하게 됩니다.

서버는 클라이언트에게 필요한 키 교환에 필요한 정보를 제공합니다. 이 과정은 생략이 가능한데, 여기에선 키교환 알고리즘을 Diffie-Hellman으로 사용했기 떄문에 소수, 원시근 등이 필요하므로 해당 데이터를 인증서 형태로 클라이언트에게 전송합니다.

이후 서버가 클라이언트로 모든 메세지를 보내는데 성공하면 다음과 같이 Server Hello Done을 표기합니다.

⑥ Client Key Exchange (Client) & ⑦ Change Chipher Spec (Client) & ⑧ Encrypted Handshake Message(Client)

키교환에 필요한 정보를 서버에 제공합니다.  이전에 주고 받았던 클라이언트의 난수와 서버의 난수를 조합하여 대칭키에 해당하는 pre master secret 이라는 키를 생성합니다. 대칭키는 앞서 보았던 ② Server Hello (Server) 과정에서 받은 서버의 난수와 클라이언트가 생성했던 난수를 사용해 AES 128-bit 알고리즘으로 생성합니다. 생성한 대칭키를 ECDHE 방식으로 암호화 하여 서버에게 전송합니다. 클라이언트는 자기가 생성했으니 이미 가지고 있고, 서버가 무사히 암호화된 pre-master secret을 받았다면 자신의 개인키로 복호화할 수 있습니다. 서버와 클라이언트 서로가 같은 pre-master secret이 공유되는 것이 확인되면, 일련의 과정을 거쳐 master secret 확정해서 암호화 통신에 사용될 대칭키로 지정합니다.

클라이언트는 ECDHE에 사용될 비대칭키를 생성해서 이전에 만들었던 대칭키를 암호화 합니다.

이 이후로 전송되는 모든 메세지는 협상된 알고리즘과 대칭키를 이용하여 암호화 됩니다. 협상된 보안 파라미터를 적용하거나 변경된 경우를 알리기 위해 서버로 전송합니다.

클라이언트는 성공적으로 핸드쉐이크를 종료하기 위해 해당 패킷을 서버로 전송합니다.

⑨ Change Chipher Spec (Server) & ⑧ Encrypted Handshake (Server)

이후 서버도 전달 받은 대칭키를 검증하여 유효한 경우, 성공적으로 핸드쉐이크를 진행했다고 알리기위해 클라이언트가 전송했던것과 동일하게 Encrypted Handshake Message 패킷을 전송해서 TLS 핸드쉐이크를 마치게 됩니다


데이터 전송 & TLS 종료

핸드쉐이크를 성공적으로 마치게 되면 서버와 클라이언트는 TLS로 암호화 통신을 진행하게 됩니다. 암호화된 데이터는 Application Data 형식의 패킷으로 표시됩니다. 데이터는 클라이언트와 서버가 공유하는 대칭키를 사용하여 암호화됩니다. 대칭키를 사용하면 데이터를 빠르게 암호화 및 복호화할 수 있습니다. 이후 암호화된 데이터는 TLS 연결을 통해 안전하게 전송됩니다. 데이터는 클라이언트와 서버가 공유하는 대칭키를 사용하여 복호화됩니다.

이후 모든 통신은 다음과 같이 암호화된 데이터를 주고 받게 됩니다.

 

TLS 통신이 종료되면 클라이언트 또는 서버는 TLS 연결이 종료됨을 나타내는 종료 알림을 전송합니다. 이후 클라이언트와 서버는 TLS 세션을 종료하고 대칭키를 폐기합니다.