TLS(Transport Layer Security)
인터넷을 사용한 통신에서 보안을 확보하려면 두 통신 당사자가 서로가 신뢰할 수 있는 자임을 확인할 수 있어야 하며, 서로간의 통신 내용이 제 3자에 의해 도청되는 것을 방지해야 한다. 따라서 서로 자신을 신뢰할 수 있음을 알리기 위해 전자 서명이 포함된 인증서를 사용하며, 도청을 방지하기 위해 통신 내용을 암호화한다. 이러한 통신 규약을 묶어 정리한 것이 바로 TLS. 주요 웹브라우저 주소창에 자물쇠 아이콘이 뜨는 것으로 TLS의 적용 여부를 확인할 수 있다.
예를 들어 인터넷 뱅킹을 하기 위해 은행의 사이트에 방문했을 때, 고객은 그 사이트가 정말 은행의 사이트가 맞는지 아니면 해커가 만든 가짜 피싱 사이트인지 확인할 수 있어야 하며, 은행 역시 자신의 서비스에 접속한자가 해당 고객이 맞는지 아니면 고객의 컴퓨터와 서버 사이에서 내용을 가로채고자 하는 해커인지 확인할 수 있어야 한다. 그리고 은행과 고객 간의 통신 내용이 다른 해커에게 도청되지 않도록 내용을 숨겨야 한다. 이럴 때 바로 은행과 고객 간에 TLS를 사용한 연결을 맺어 안전하게 통신을 할 수 있다.
SSL 인증서의 역할은 다소 복잡하기 때문에 인증서의 메커니즘을 이해하기 위한 몇가지 지식들을 알고 있어야 한다. 인증서의 기능은 크게 두가지다. 이 두가지를 이해하는 것이 인증서를 이해하는 핵심이다.
- 클라이언트가 접속한 서버가 신뢰 할 수 있는 서버임을 보장한다.
- SSL 통신에 사용할 공개키를 클라이언트에게 제공한다.
왜 공개키를 쓰는 걸까?
보내는 사람이 암호화를 하고, 받아보는 쪽에서 복호화를 하는 방식은 변환 알고리즘이 들통나면 모든 통신이 그대로 누설된다. 이런 암호화 방식은 인터넷에서 사용하지 않는다.
암호화에서 중요한 것은 알고리즘 자체를 비밀로 하는 것이 아니라, 알고리즘이 알려져도 안전하게 통신할 수 있는 것이다. 현재 많이 사용하는 브라우저는 대부분 핵심 소스 코드를 누구나 볼 수 있는 오픈 소스로서 공개한다. 그러므로 암호화 알고리즘 자체를 비밀로 해서는 안 된다.
현재 일반적으로 사용하는 방식은 암호화 알고리즘은 공개하고, 그 암호화에 사용하는 데이터(키)를 따로 준비하는 방식이다. TLS에서 사용되는 방식으로는 공통 키 방식과 공개 키 방식 두 종류가 있다.
공통 키 방식
자물쇠를 잠글 때와 열 때 모두 같은 열쇠를 사용하는 방식이다. 대칭 암호라고도 불린다. 마치 무인 택배함과 같아서 택배함을 잠글 때 설정한 것과 같은 번호로 연다. 따라서 통신하는 사람끼리는 이 번호를 공유할 필요가 있다.통신의 공통 키 방식 알고리즘과 물리적 키 차이는 키와 암호와 전후의 데이터가 모두 데이터라는 점이다. 물리적 세계에서 은닉화는 키를 숨기는 것이지만, 암호화는 키 데이터로 원본 데이터를 파괴하는 것이다. 키만 있으면 망가진 데이터를 원래대로 수리할 수 있으므로, 받은 쪽에서 데이터를 복원해 읽는다. TLS에서는 일반 통신의 암호화에 사용한다.
공개 키 방식
비대칭 암호라고도 한다. 공개 키 방식에서 필요한 것은 공개 키와 비밀 키이다. 공개 키는 이름 그대로 전 세계에 공개해도 문제 없지만, 비밀 키는 다른 사람에게 알려져서는 안 된다. 공개 키 방식에서는 집 열쇠와 달리 암호화 키와 암호해독 키가 따로 있다. 암호화하는 것이 공개 키고 해독하는 것은 비밀 키이다. 사물에 비유하면 공개키는 자물쇠이고, 비밀키는 열쇠이다. 같은 자물쇠를 여러 개 가지고 있다가 상대방한테 보낸다. 비밀 통신을 원하는 사람은 그 자물쇠를 잠궈 반송한다. 다른 사람은 키를 가지고 있지 않아 열 수 없지만 비밀키를 가진 사람은 그 자물쇠를 열 수 있다.
디지털 서명은 공개 키 방식을 응용한 예이다. 거꾸로 열쇠를 나누어주고 자물쇠를 비밀로 해두는 것과 같은 이미지이다. 편지 본문에는 자물쇠로 잠근 데이터도 함께 첨부해 보낸다. 받는 사람이 공개된 키를 사용해 자물쇠를 열었을 때 본문과 동일한 것이 나오면 메시지가 조작되지 않은 것을 알 수 있다. 이게 바로 디지털 서명이다.
공개 키 방식에서는 키와 암호화된 데이터로 원본을 복원할 수는 있어도, 자물쇠인 비밀 키를 추출할 수는 없다.
작동 방법
네트워크 통신은 핸드쉐이크 -> 세션 -> 세션 종료의 과정을 거친다. 쉽게 말해 서로가 어떤 TRS 버전을 사용 가능한지 확인하고, 인증서를 사용해 서로를 믿을 수 있는지 확인한 뒤 서로간의 통신에 쓸 암호를 교환하는 것이다. 그 다음부터는 서로 교환한 암호를 사용해 제3자가 도청할 수 없는 암호화된 통신을 하면 된다.
공개키 암호 방식은 계산이 복잡해서 매우 많은 컴퓨터 자원을 사용하므로 효율을 위해 ssl은 공개키+대칭키 방식을 사용한다.
- 실제 데이터: 대칭키
- 위의 대칭키를 서로 공유하기 위한 암호화 방식: 공개키
다시 말해 대칭키를 공개키로 암호화해서 서로 공유
1. client hello
클라이언트에서 서버에 ClientHello 메시지를 보낸다. 이 단계에서 주고 받는 정보는 아래와 같다.
- 클라이언트 측에서 생성한 랜덤 데이터 : 아래 3번 과정 참조
- 클라이언트가 지원하는 암호화 방식들 : 클라이언트와 서버가 지원하는 암호화 방식이 서로 다를 수 있기 때문에 상호간에 어떤 암호화 방식을 사용할 것인지에 대한 협상을 해야 한다. 이 협상을 위해서 클라이언트 측에서는 자신이 사용할 수 있는 암호화 방식을 전송한다.
- 세션 아이디 : 이미 SSL 핸드쉐이킹을 했다면 비용과 시간을 절약하기 위해서 기존의 세션을 재활용하게 되는데 이 때 사용할 연결에 대한 식별자를 서버 측으로 전송한다.
2. server hello
클라이언트의 메시지를 받은 서버는 ServerHello 메시지를 클라이언트에게 보낸다. 여기에는 ClientHello 메시지의 정보 중 서버에서 사용하기로 선택한 TLS 버전, 세션 식별자, 암호 설정 등의 정보가 포함된다.
그리고 서버가 클라이언트에 Certificate 메시지를 보낸다. 여기에는 서버의 인증서가 들어간다. 이 인증서는 별도의 인증 기관에서 발급받은 것이며, 서버가 신뢰할 수 있는 자임을 인증한다. 전송이 끝나면 ServerHelloDone 메시지를 보내 끝났음을 알린다.
이 단계에서 주고 받는 정보는 아래와 같다.
- 서버 측에서 생성한 랜덤 데이터 : 아래 3번 과정 참조
- 서버가 선택한 클라이언트의 암호화 방식 : 클라이언트가 전달한 암호화 방식 중에서 서버 쪽에서도 사용할 수 있는 암호화 방식을 선택해서 클라이언트로 전달한다. 이로써 암호화 방식에 대한 협상이 종료되고 서버와 클라이언트는 이 암호화 방식을 이용해서 정보를 교환하게 된다.
- 인증서
3. 인증서 확인
클라이언트는 서버에서 받은 인증서를 검증한다. 인증서의 유효 기간이 만료되지 않았는지, 그 인증서가 해당 서버에게 발급된 인증서가 맞는지 등을 확인한다. 인증서를 신뢰할 수 있다고 판단하였다면 1, 2번과정에서 생성한 랜덤 데이터들을 조합해서 pre-master secret을 생성한다. 여기서의 pre master secret 키는 대칭키로 활용 예정이다.
이 때 사용할 암호화 기법은 대칭키이기 때문에 pre master secret 값은 제 3자에게 절대로 노출되어서는 안된다
4. 클라이언트가 서버에 pre master secret 전송
클라이언트는 pre-master secret을 생성한 뒤, 서버가 보낸 인증서에 포함된 공개 키를 사용해 암호화한다. 이렇게 암호화된 pre-master secret을 ClientKeyExchange 메시지에 포함시켜 서버에 전송한다.
5. 클라이언트 인증서 확인
서버는 클라이언트에서 받아온 pre master secret 키를 자신이 가진 비공캐 키를 가지고 복호화. 이후 pre master secret 키는 이후 대칭키 방식을 사용할 때(데이터를 주고 받을 때) 사용
6. master secret 및 session key(대칭키) 생성
세션 키는 앞으로 서버와 클라이언트 간의 통신을 암호화하는데 사용할 것이다. 물론 클라이언트 역시 자신이 만들어낸 pre-master secret을 알고 있으므로, 같은 과정을 거쳐 세션 키를 스스로 만들 수 있다.
7. session key를 대칭키 방식으로 이용하여 통신
이제 서버와 클라이언트는 각자 동일한 세션 키를 가지고 있으며, 이를 사용해 대칭 키 암호를 사용하는 통신을 할 수 있다. 따라서 우선 서로에게 ChangeCipherSpec 메시지를 보내 앞으로의 모든 통신 내용은 세션 키를 사용해 암호화해 보낼 것을 알려준 뒤, Finished 메시지를 보내 각자의 핸드셰이킹 과정이 끝났음을 알린다.