TLS
개요
SSL이라고도 불렸지만, 점차 버전이 올라가면서 현재는 TLS로 불리는 프로토콜.
TLS는 웹 상에서 전송되는 데이터를 암호화하기 위해 고안된 프로토콜로, HTTPS프로토콜에서 기본으로 사용한다.
간단하게만 요약하자면 서버와 클라이언트는 실제 데이터를 암호화하여 전송한다.
이를 위해서 대칭키를 사용하는데, 이 대칭키를 교환하기 위해서 공개키 암호화 알고리즘을 활용한다.
그런데 이때 클라이언트는 웹 상에 자신의 주소를 노출하고 있는 서버를 함부로 신뢰할 수 없다.
그렇기 때문에 PKI, 즉 공개키 인프라 구조를 활용하여 서버의 신원을 검증한다.
이 문서는 PKI 문서에서 정리하던 내용을 분리시켜 새로 문서를 만들었다.
그래서 여기에 나오는 개념들이 어렵다면 해당 문서를 먼저 보는 것이 좋다.
상세 흐름
TLS는 총 4가지의 하위 프로토콜로 구성돼있다.
- Record Protocol - 통신 주체간 암호키를 공유하기 위한 계산, 통신 수립 후 데이터를 암복호화하는 방식을 정의하는 프로토콜
- Handshaking Protocol - 통신 주체간 암호키를 공유하기 위한 일련의 동작 흐름을 정의하는 프로토콜
- Change Cipher Spec Protocol - 통신 간 암호 방식을 바꾸는 방법을 정의하는 프로토콜
- Alert Protocol - 문제가 있을 때 경고를 상대에 전달하는 방식을 정의하는 프로토콜
TLS(1.2)는 이렇게 크게 봤을 때는 두 계층으로 나뉘어져 있고, 쩌리 프로토콜 두 개가 핸드쉐이킹 프로토콜에 포함돼있다.
이중에서 가장 핵심적으로 볼 만한 것은 핸드쉐이킹 프로토콜이라, 이걸 위주로 정리했다.[1]
Record Protocol
하위 계층에 속하는 프로토콜로, 상위 계층(핸드쉐이킹)에서 설정된 방식에 의거해 데이터 암호화, 단편화, 압축 등의 작업을 수행하는 레코드 층에 대한 프로토콜이다.
이 프로토콜이 책임지는 것은 기밀성과 신뢰성이다.
서버와 클라 간의 연결을 대칭키로 암호화하는 과정이 여기에서 일어난다.
대부분 암호화되지만, 설정에 따라서 암호화하지 않는 통신도 허용한다.
여기에 MAC을 활용해 무결성을 보장하는 것도 이 프로토콜에서 수행된다.
이 프로토콜이 동작하기 위해 서버, 클라의 난수, 마스터 시크릿, 해시 함수, 난수생성함수 등의 값이 정해진다.
이들을 이용해 최종적으로 서버와 클라는 반드시 다음의 값들을 같은 상태로 동기화해야 한다.
- 마스터 시크릿 - 이 놈으로부터 실제 암호화에 사용되는 모든 대칭키, 기타 필요한 값을 꺼낸다.
- 데이터 압축 방식
- 데이터 암호화 방식
- MAC 키
- 시퀀스 번호 - 연결할 때마다 올라가는 번호
이것들이 같은 상태라면 서버와 클라는 통신 시 데이터를 복호화하고, 압축을 풀고, 무결성 검증을 할 수 있게 된다.
이 프로토콜에서 안전성이 전부 확보되기 때문에, 이 프로토콜이 성립하기 위해 각종 필요한 값들을 서버와 클라가 공유하는 과정이 필요하다.
Handshaking Protocol
그것이 바로 이 프로토콜이다!
핸드쉐이킹 프로토콜은 위 레코드 프로토콜을 세팅하고 검증하기 위한 절차를 담은 프로토콜이다.
핸드쉐이킹 과정은 대충 4번 오고 간다.
여기에 에러가 발생하거나, 중간에 암호 방식을 교체한다던가 하는 각종 추가적인 과정이 있을 수 있긴 한데, 이것들은 생략했다.
그런 트래픽은 항상 발생하는 것은 아니기도 하고, 핵심 플로우에 해당하진 않는다.
빨간색 블록은 클라이언트의 신원까지 검증하는 [[#mTLS]]로 핸드쉐이킹이 이뤄질 때만 발생하는 추가적인 트래픽이다.
- 클라이언트 헬로
- 클라이언트에서 사용 가능한 각종 버전과 알고리즘 리스트를 전달한다.
- 또한 여기에서 SNI(Server Name Indicator)를 헤더에 같이 넣어서 보냄으로써 클라가 서버를 어떤 도메인으로 인식하고 있는지를 보낸다.
- 클라 난수도 같이 전달한다.
- 서버 헬로
- 클라에게 받은 버전이나 알고리즘 등에서 서버 측도 사용 가능한 것을 선별하여 보낸다.
- 여기에는 최대한 최신 버전을 쓴다, 뭐 이런 몇 가지 규칙이 있다.
- 서버는 클라가 인식하고 있는 도메인(SNI)에 대한 인증서를 전달한다.
- 이 인증서는 신뢰되는 서명 기관으로부터 서명받은 상태로, 서명 기관의 인증서도 같이 전달한다.
- 서명 기관이 상위 서명 기관을 두는 식으로 꼬리를 문다면 체인 인증서를 한꺼번에 전부 전달한다.(이거 알아보고 싶어서 RFC까지 뒤졌다)
- 이때 서버 난수를 같이 전달한다.
- 대칭키 교환 방법 중, 디피 헬만 알고리즘이 선택된 경우에는 대칭키 교환을 위한 추가 메시지를 보낸다.
- 클라에게 받은 버전이나 알고리즘 등에서 서버 측도 사용 가능한 것을 선별하여 보낸다.
- 클라 피니쉬
- 클라이언트는 인증서 검증을 시작한다.
- 최상단에 서버 인증서가 있고, 여기에서 발행자(Issuer) 값을 꺼낸다.
- 체인 인증서가 이 다음에 있으면 발행자 값을 토대로 서버를 인증하는 인증 기관이 적힌 인증서를 찾는다.
- 그 인증서에는 인증 기관의 공개키가 적혀있을 테니, 그것으로 서버 인증서를 검증한다.
- 꼬꼬무한다..
- 마지막 남은 인증서의 발행자 값은 로컬 환경에 저장된 루트 CA의 인증서로 검증한다.
- 검증을 마치고 Pre Master Secret 값을 만들어 서버의 공개키로 암호화하여 보낸다.
- 디피 헬만 방식이라면 암호화를 거치지 않는다고 한다.
- 클라이언트는 인증서 검증을 시작한다.
- 서버 피니쉬
- 문제 없으면 그냥 끝 날린다!
레코드 프로토콜에서 필요한 값 중 하나는 마스터 시크릿이란 값이었다.
이 값은 클라 난수 + 서버 난수 + Pre Master Secret을 합쳐 만들어진다.
각 난수는 암호화되지 않았지만, Pre Master Secret는 클라가 서버의 공개키로 암호화했기에 서버만이 복호화할 수 있다.
이를 바탕으로 Master Secret을 만들면 둘만의 대칭키를 만드는데 활용할 수 있다!
참고로 세션 유지 및 재개에 대한 절차도 잘 마련돼있다.
세션 시간이 오래 되거나 데이터가 더 이상 오고가지 않을 때, 클라에게 서버가 헬로 좀 해달라 요청(HelloRequest)하기도 한다.
mTLS
mutual TLS는 클라이언트의 신원도 인증서를 기반으로 검증하는 추가 단계가 포함된 프로토콜이다.
별도로 분리된 프로토콜은 아니고, 그냥 위의 동작 흐름 상에서 클라 인증서를 교환하는 과정이 조금 추가될 뿐이다.
일반 사용자가 브라우저를 이용할 때 사용되진 않고, 서버 간 통신을 할 때 서로를 신뢰하기 위한 수단으로 사용된다.
쿠버네티스 인증에서는 이 방식을 이용해 접근하는 클라의 신원을 체크하기도 한다.
관련 문서
이름 | noteType | created |
---|---|---|
TLS downgrade attack | knowledge | 2024-06-20 |
openssl | knowledge | 2025-01-18 |
cfssl | knowledge | 2025-01-23 |
PKI | knowledge | 2025-03-10 |
Cert Manager | knowledge | 2025-03-15 |
TLS | knowledge | 2025-04-16 |
Istio PeerAuthentication | knowledge | 2025-05-04 |
SPIFFE | knowledge | 2025-05-04 |
6W - PKI 구조, CSR 리소스를 통한 api 서버 조회 | published | 2025-03-15 |
5W - 이스티오 mTLS와 SPIFFE | published | 2025-05-11 |
7W - 이스티오 메시 스케일링 | published | 2025-06-09 |
E-api 서버 감사 | topic/explain | 2025-01-21 |
E-이스티오 메시 스케일링 | topic/explain | 2025-06-08 |