
이번 글에서는 이전 글들에서 다뤘던 암호화 관련 개념들이 종합된 결과인 SSL/TLS에 대해서 알아보도록 하겠다.

SSL은 넷스케이프(Netscape)에서 1994년에 처음 개발된 보안 프로토콜로, TLS의 이전 버전이다.
기존 HTTP는 평문 형태로 데이터가 전송되었기에, 제3자가 데이터를 가로채면 데이터의 내용을 읽을 수 있다는 보안상 문제점이 존재했다.
이러한 문제점을 해결하기 위해, SSL은 클라이언트와 서버 간의 통신을 암호화하여 제3자가 데이터를 중간에서 탈취하거나 변경하지 못하도록 만들어졌다.
이렇게 SSL/TLS를 사용하는 프로토콜이 HTTPS(HTTP Secure)이다.
SSL은 1.0, 2.0, 3.0 세 가지 버전이 존재하는데, 모든 버전의 SSL에서 취약점이 발견되었다. 또한, SSL은 1996년 SSL 3.0 이후 업데이트되지 않고 있고, 앞으로 사용이 중단될 것으로 여겨지고 있다.
TLS(Transport Layer Security)는 SSL의 후속 버전으로, SSL의 약점을 보완하고 더 높은 보안을 제공하기 위해 1999년에 처음 도입되었다. TLS는 1.0, 1.1, 1.2, 1.3의 네 가지 버전이 존재하고, 2020년 3월부터 TLS 1.0 및 1.1은 더 이상 지원되지 않고 있다.
현재 대부분의 보안 통신에서 SSL 대신 TLS가 사용되고 있으며, TLS는 지속적으로 업데이트되면서 더 강력한 보안 기능을 제공하고 있다. (현재 대부분의 경우 TLS 1.2가 사용된다.)
📌 SSL/TLS의 역대 주요 취약점은?
출처: https://spri.kr/posts/view/19827?code=industry_trend
해당 사이트에서 SSL/TLS의 주요 보안 이슈들에 대한 구체적인 내용을 확인할 수 있다.
위에서 말하는 SSL 2.0 취약점이란 기본적으로 약한 암호화 알고리즘 사용과 짧은 키 등으로 인한 설계 결함을 의미한다.
SSL 3.0의 주요 취약점은 해당 버전의 CBC(Cipher Block Chaining) 모드 패딩 처리 방식의 취약점을 이용한 POODLE 공격이다. TLS 연결 시도를 모두 무시(drop)하고 SSL 3.0 연결을 유도하는 방식으로 POODLE 공격이 가능했기 때문에, SSL은 사용이 중지되었다.
| 항목 | SSL | TLS |
|---|---|---|
| 의미 | Secure Sockets Layer, 보안 소켓 계층 | Transport Layer Security, 전송 계층 |
| 버전 | SSL은 버전 1.0, 2.0, 3.0이 존재하며, 현재 TLS로 대체되었다. | TLS는 SSL의 업그레이드된 버전으로, TLS는 버전 1.0, 1.1, 1.2 및 1.3이 존재한다. |
| 사용 | 모든 SSL 버전이 더 이상 사용되지 않는다. | TLS 버전 1.2 및 1.3이 현재 사용되고 있다. |
| 알림 | SSL은 암호화되지 않은 두 가지 유형의 알림 메시지 존재 | TLS는 암호화된 다양한 유형의 알림 메시지 존재. |
| 인증 | SSL은 MAC 사용. | TLS는 HMAC 사용. |
| 알고리즘 | SSL은 알려진 보안 취약점이 있는 이전 알고리즘을 지원. | TLS는 고급 암호화 알고리즘을 사용. |
| 핸드셰이크 | SSL 핸드셰이크는 복잡하고 느리다. | TLS 핸드셰이크는 단계가 적고 연결 속도가 빠르다. |
OSI 7계층(OSI 7 Layer)에 대해 알고 있다면, TLS의 이름을 통해 "Transport Layer", 전송 계층을 떠올릴 것이다.
📌 OSI 7계층(OSI 7 Layer) 설명 글
그렇다면 TLS는 전송 계층 내부에 있는가? 그렇지는 않다.

TLS는 명확히 어떠한 계층에 있다고 표현하기 어렵다. 그 이유는 다음과 같다.
TCP 위에서 작동
TLS는 전송 계층(Transport Layer) 위에서 작동한다. 즉, TLS는 TCP와 같은 전송 프로토콜 위에서 데이터를 암호화하고 보호한다.
암호화 세션을 설정
TLS는 암호화 세션을 설정하고 관리한다. 이 기능은 일반적으로 세션 계층(Session Layer)에서 수행되는 작업과 관련이 있다.
데이터 암호화 제공
TLS는 데이터 암호화를 제공하는데, 데이터 암호화는 프레젠테이션 계층(Presentation Layer)의 역할로 간주될 수 있다.
따라서 TLS는 주로 위의 그림처럼 응용 계층과 전송 계층 사이의 보안 계층으로 표현된다.
TLS는 아래의 두 개의 계층으로 구분된다.
TLS의 Handshake Layer는 통신을 시작하기 전에 암호화 세션을 설정하는 역할을 한다. 이 과정에서 암호화 방식, 인증 방법, 세션 키 등의 중요한 파라미터가 결정된다. 자세한 내용은 TLS Handshake 파트에서 알아보자.
Handshake Layer는 3개의 서브 프로토콜로 나누어진다.
Handshake 프로토콜
TLS의 Handshake 프로토콜은 클라이언트와 서버가 암호화 방식과 세션 키를 협상하여 안전한 통신을 준비하는 과정이다.
ChangeCipherSpec 프로토콜
ChangeCipherSpec 프로토콜은 핸드쉐이크를 통해 대칭키 생성이 완료된 후, 클라이언트와 서버가 새로운 암호화 설정을 적용하도록 지시한다.
Alert 프로토콜
Alert 프로토콜은 TLS 연결의 상태나 오류를 클라이언트와 서버에게 알려주는 역할을 한다.
데이터의 실제 전송을 처리한다. Handshake Layer에서 설정된 암호화 세션을 바탕으로, Record Layer는 애플리케이션 데이터를 안전하게 보호하기 위해 암호화 및 무결성 검사를 수행한다.
인증서에 대한 개념을 다시 짚고 넘어가자면, 말 그대로 서버가 신뢰할 수 있는 진짜 서버인지 확인하기 위한 요소이다.
예를 들어 사용자가 google.com에 접속한 경우, 사용자는 소통하는 상대방이 google이라는 것을 어떻게 확신할 수 있을까?
아래는 인증서의 실제 예시이다.

인증서의 정보에는 발급자(CA), 소유자(도메인), 유효 기간, 서명 알고리즘, 공개 키 등이 포함된다.
위의 예시에서 발급자는 Google Trust Services, 소유자는 *.google.com, 유효 기간은 발급일과 만료일이 명시되어 있고, 서명 알고리즘은 SHA-256로 적혀있다. 인증서의 지문 또한 확인할 수 있다.

인증서의 세부 정보 항목에서는 인증서 서명 값 또한 확인할 수 있다. 지문과 서명의 차이는 아래의 인증서 발급 과정에서 알아보자.
여기서 CA(Certificate Authority)란 인증서를 발급해주는 기관으로, 엄격하게 공인된 기업들로 구성되어 있다.
사용자는 인증서를 통해 해당 CA가 신뢰할 수 있는 기관인지, 인증서의 날짜가 유효한지, 발급 대상의 주소가 일치하는지 여부를 확인하게 된다.
📌 CA와 Root CA 차이
Root CA는 CA 계층 구조에서 가장 높은 위치에 있는 CA이다. 즉, 특정 CA 기관이 Root CA가 아니라면, 이 CA 기관은 또다른 상위 CA에게 인증서를 발급받은 것이다. 이렇게 연결된 일련의 인증서를 인증서 체인(Certificate Chain)이라고 한다.
위의 설명만으로는 인증서로 서버를 인증할 수 있다는 것이 잘 와닿지 않는다. 인증서가 위조되었을 수도 있지 않을까?
먼저 인증서 발급 과정을 살펴보자.

위는 구체적인 인증서 발급 과정을 알기 쉽게 그림으로 그려본 것이다.
서버는 인증서를 요청하기 위해 CSR(Certificate Signing Request)을 생성 후, CA에 제출한다. CSR에는 도메인 이름과 공개키 등이 포함되어 있다.
CA는 CSR에 포함된 정보를 검토한 후, CSR에서 제공된 정보를 바탕으로 인증서를 생성한다.
CA는 서버의 공개키를 SHA-256 등으로 해시하여 지문으로 등록한다.
CA는 앞서 등록한 지문을 CA의 개인키로 암호화하여 서명으로 등록한다.
위의 정보들이 담긴 인증서가 발급된다.
서버는 CA로부터 발급 받은 인증서를 클라이언트에게 전달한다.
클라이언트는 인증서를 확인한 후, 해당 인증서를 발급한 CA의 공개키를 CA List에서 찾는다. (이 때 CA 리스트는 PC 또는 브라우저에 기본적으로 저장되어 있다.)
일치하는 CA의 공개키를 찾으면, 해당 키로 인증서의 서명을 복호화한다. (CA의 개인키로 암호화 된 데이터는 CA의 공개키로 복호화 할 수 있다. 이 때의 결과는 당연히 "서버의 공개키를 해시한 결과"가 될 것이다.)
클라이언트는 서버의 공개키를 해시한 후, 8번의 결과와 비교한다. 두 결과가 같을 경우, 해당 인증서가 위조되지 않았음을 인증하게 되는 것이다.
마지막으로 TLS Handshake의 과정을 단계적으로 알아보자.

Client Random
클라이언트가 생성한 무작위 숫자를 전송한다. 해당 숫자는 비밀키 생성에 사용된다.
TLS Version
클라이언트의 TLS 버전을 전송한다.
Preferred Cipher Suites
클라이언트가 지원하는 암호화 방식 목록을 전송한다.
Extensions
TLS에 정의된 확장 기능들을 포함할 수 있다.

Server Random
서버가 생성한 무작위 숫자를 전송한다.
TLS Version
서버의 TLS 버전을 전송한다.
Selected Cipher Suite
서버와 클라이언트의 암호화 방식 목록을 비교한 후, 암호화 방식을 선택하여 클라이언트에게 통지한다. (가능한 가장 강한 암호화 방식으로 선택된다.)
Extensions
클라이언트는 세션에서 사용하고 싶은 확장 기능 목록을 서버에 전송하고, 서버는 지원하는 확장 기능을 클라이언트에 다시 보낸다. 확장 기능의 예시로 SNI(Server Name Indication)가 있다.
📌 SNI(Server Name Indication)
동일한 IP 주소와 포트를 공유하는 여러 도메인에 대해 각기 다른 SSL/TLS 인증서를 사용할 수 있게 해주는 기술이다.
SNI String은 Handshake가 완료되기 이전에 전송되기에, 사용자가 방문하려는 웹사이트의 주소를 알아낼 수 있다. (HTTPS로 암호화된 웹사이트의 URL은 보이지 않는다.) 대한민국은 이렇게 SNI-based Filtering을 이용해 대규모 웹사이트 차단을 하고 있는 것이다.

RSA 공개키 방식을 사용하여 서버의 신원을 확인하고, Diffie-Hellman 키 교환을 사용하여 클라이언트와 서버 간의 비밀 공유 키를 교환한다.

Server Key Exchange 단계는 암호화 방식으로 Diffie-Hellman을 사용하는 경우에만 존재한다. RSA를 사용하는 경우 생략된다.
Diffie-Hellman Key Exchange & RSA 설명

TLS Handshake에서 서버의 역할이 종료된다.

해당 단계에서 RSA에서는 암호화된 Premaster Key가 전송되고,
Diffie-Hellman에서는 클라이언트의 공개 키가 전송된다.
양측은 공유된 정보를 통해 Shared Master Secret을 계산하기 시작한다. 그 후, Master Secret에서 여러 가지 키(메시지 전용 키, HMAC 전용 키, AES 초기화 벡터)를 파생시킨다.

양측은 공유 비대칭 키 쌍을 얻게 되고, 이후의 통신은 정부 암호화된다.
네트워크를 공부하며 TCP Handshake, TLS Handshake, Session, Cookie 등 여러 개념들을 접하게 된다.
실제로 우리가 특정 웹사이트에 접속하여, 로그인을 진행하고, 개인 정보를 열람할 때, 어떠한 흐름으로 각각의 이벤트가 발생하는지 생각해보면 좋을 것 같다.