Skip to main content

SSL/TLS이란? (feat. HTTP/HTTPS, CA, 인증서)

글에서 다루는 내용

  • Hypertext, HTML, Protocol, HTTP/HTTPS는 무엇인가
  • CA, 인증서, 전자 서명이란 무엇인가
  • 암호화 방식 중 대칭키, 공개키 방식은 무엇인가
  • SSL/TLS는 무엇인가
  • SSL/TLS의 과정은 어떻게 되는가

TL;DR

SSL/TLS는 암호화 프로토콜의 일종으로, CA가 발급하는 인증서를 활용해 서버의 신뢰성을 확인하는 것과, 인증서에 포함된 서버의 공개키를 활용해 대칭키를 암호화 한다는 것이 핵심이다.

들어가며

금요일 오후, 슬슬 퇴근을 준비하려던 때에 갑자기 사건이 발생했다. 잘 동작하던 외부 서버에서 계속해서 에러를 뱉었다. 원인을 파악하던 중, 해당 서버를 관리하는 회사에서 “내부에 이슈가 있었다. TLS 버전을 1.2로 설정하면 문제가 해결될 것이다”라는 공지를 올렸다. 가장 큰 문제는 TLS가 네트워크와 관련된 용어라고만 알고 있었을 뿐 잘 알지 못했기 때문에, 어디서 어떻게 설정을 해야 하는지 몰랐다는 것이다. 결론적으로는 TLS 버전을 1.2로 설정하는 것이 아닌, 다른 방법으로 해결이 되긴 했다. 이 포스팅은 해당 이슈를 다루며 배웠던 HTTP/HTTPS, SSL/TLS에 대해 정리한 글이다.

용어 정리

bottom-up 방식으로 필요한 용어들에 대해 간략히 알아보자.

Hyptertext

Hypertext는 텍스트를 넘어선 텍스트로, 다른 텍스트의 링크를 포함하는 텍스트를 지칭하는 용어이다. 1965년 경에 만들어졌다고 한다. 여기서는 “하이퍼텍스트”라는게 있구나 하는 정도로 받아들이자. 참고로, 하이퍼텍스트는 보통 HTML을 통해 작성된다. HTML은 Hypertext Markup Language의 줄임말이고, 마크업 언어는 문서의 구조를 나타낼 때 사용된다.

Protocol

프로토콜은 통신 규약으로, 서로 소통할 때의 약속 혹은 규칙이라고 생각하면 된다. 군대에서 사용하는 통신보안도 일종의 프로토콜이라고 볼 수 있을 듯 하다.

HTTP

Hyptertext Transfer Protocol의 약자다. 하이퍼텍스트(=다른 텍스트의 링크를 포함한 텍스트)를 전송할 때 사용하는 프로토콜(=약속)이다. OSI 모델 및 TCP/IP 모델의 가장 상위 계층인 Application Layer에서 사용된다.

HTTPS

HTTPS는 HTTP에 Secure(보안)을 추가한 것으로, HTTP에 보안을 강화시킨 프로토콜이다. 그리고, 보안을 강화시킬 때 사용한 프로토콜이 SSL/TLS이다.

SSL/TLS

SSL/TLS는 인터넷에서 데이터를 안전하게 주고 받기 위해 사용되는 암호화 프로토콜의 일종이다. 인증서 교환을 통해 보안을 강화하는 것이 핵심이다. 처음에는 SSL 1.0이 개발되었고 이후 버전이 업데이트 되면서, SSL 3.0을 TLS 1.0이 계승했다. 이후에는 TLS만 계속 업데이트 되었는데, SSL이라는 용어가 더 익숙하다보니 TLS를 SSL로 지칭하기도 한다. 따라서, SSL과 TLS는 모두 TLS를 지칭하는 용어로 받아들이면 될 것 같고, 실제로는 TLS를 사용하는 것으로 이해하면 되겠다.

암호화 종류

SSL/TLS에 대한 설명으로 넘어가기 전에, 대표적인 암호화 방식 2가지에 대해 알아보자.

대칭키

암호화와 복호화에 동일한 key를 사용하는 방식이다. 쉽고 빠르지만, key를 주고 받는 와중에 유출되면 공격당할 수 있는 위험성이 있어서 안전성이 떨어진다. 또한, 둘 중에 한 명이라도 key를 유실하면 양쪽 모두가 위험에 처할 수 있다.

공개키

암호화와 복호화에 다른 key를 사용하는 방식이다. 이 때, 재밌는 점은 암호화와 복호화를 위한 pair key를 생성하고, 서로가 서로의 암호화/복호화에 사용된다는 점이다. A와 B가 pair라고 생각해보자. A로 암호화하면 B로 복호화할 수 있고, B로 암호화하면 A로 복호화할 수 있다.

SSL/TLS 인증서

client가 server에 접속을 한다고 하자. 이 때, client가 접속하려는 server의 신원은 어떻게 보장받을 수 있을까? 이럴 때 사용되는 것이 인증서(certificate)이다. 어떤 계약이 효력이 있으려면, 계약을 진행한 당사자들의 “서명”을 받아야 한다. 네트워크 통신에서 “서명” 역할을 하는 것이 “인증서”이다. 따라서, 인증서를 “전자 서명”이라고도 부른다.

그렇다면, server의 신원에 대해 누군가가 괜찮다고 서명을 해줘야 하는데 누가 해줄 수 있을까? 그런 기관들을 CA (Certificate authority) 혹은 Root Certificate라고 부른다. 이들은 아무나 할 수 없고, 전세계적으로 공인된 몇 개의 기업만이 가능하다. CA가 되는 심사는 매우 엄격하고, 이들은 자신들의 key를 엄격하게 관리해야 할 의무가 있다. key가 유출되는 경우, CA로서의 자격이 사라질 수도 있다.

server는 자신의 신원을 보증하기 위해서 CA로부터 인증서를 받아야 한다(=구입). 이 때, server는 CA에게 어떤 domain을 사용하는지, client과 통신할 때 사용할 public key는 어떤 것인지 등등을 제공해야 한다. 그러면 CA는 본인들의 private key를 이용해 server에게 받은 정보를 암호화 해서 인증서를 만들고, 인증서를 server에게 전달한다.

server: “Hey CA! 인증서 살게!”
CA: “OK. 그러면 도메인이랑 public key를 전달해줘~”
server: “A도메인 사용할꺼고, public key로는 B 사용할게!”
CA: “우리 회사의 private key를 이용해서 [A 도메인, B key]를 암호화 했어! 여기 인증서야! private key는 철저하게 보안을 유지하고 있으니, 걱정하지 말라구~”

server는 이렇게 CA로부터 자신의 신원을 보증받을 수 있는 인증서를 취득했다. client는 server에 접속하려고 했고, server로부터 인증서를 전달 받았다. 인증서에는 어떤 기관이 인증을 해줬고, 암호화 된 데이터가 들어있었다. client는 이 기관이 믿을만한 기관인지 어떻게 알 수 있을까? 답은 브라우저에 있다. 우리가 사용하는 브라우저에는 CA에 대한 정보가 이미 내장되어 있다. 정확하게는 CA의 목록과, 각 CA의 public key가 내장되어 있다. 따라서, client는 브라우저에 저장된 정보를 통해 server로부터 전달 받은 인증서의 유효성을 검증할 수 있게 된다.

client: “Hi, server. 통신하자~”
server: “OK. 여기 CA로 부터 받은 인증서야”
client: “브라우저에 저장된 정보로 인증서 좀 확인해볼게~”
client: “OK! CA 목록에 있는지 확인했고, 보내준 데이터도 CA public key를 이용해서 인증서 내용 복호화 했고, 너네(=server)가 사용하는 public key도 확인했어!”

지금까지 SSL/TLS에서 사용되는 인증서에 대한 내용을 알아봤다. 이제, SSL/TLS가 어떤 과정을 통해 진행되는지 알아보자.

SSL/TLS 진행 과정

[client] Client Hello

모든 것은 client가 server에 접속하며 시작된다. 이 과정을 client hello라고 부른다. 이 때, client는 server에 본인이 생성한 랜덤한 데이터와, 사용 가능한 암호화 목록과, 세션 아이디(존재하는 경우에만)를 전송한다.

[server] Server Hello

client로부터 정보를 전달 받은 server는, 반대로 client에게 정보를 준다. 이 과정을 server hello라고 부른다. 이 때 전달되는 데이터로는 server가 생성한 랜덤한 데이터와, client가 보내준 암호화 목록 중에 선택한 암호화 방식과, CA로부터 구매한 인증서가 있다.

[client] 인증서 확인

client는 server에게 전달 받은 인증서를 브라우저에 내장된 정보를 이용해 확인한다. 확인이 완료되었다면, 인증서를 복호화해서 server의 public key를 얻는다.

[client] pre master secret 생성

client는 Client hello 단계에서 server에 전송한 랜덤 데이터와, Server hello 단계에서 server로부터 전달 받은 랜덤 데이터를 조합해서 pre master secret을 생성한다. 그리고, server의 public key를 사용해 pre master secret을 암호화해서 server에 전달한다.

[server] pre master secret 획득

server는 client가 보내준 pre master secret을 자신이 가지고 있던 private key로 복호화 한다. 이를 통해, client와 server 모두가 pre master secret을 가지고 있게 되었다.

[client, server] session key 생성

client, server 모두 pre master secret을 사용해 master secret을 생성한다. 그리고, master secret을 활용해 session key를 생성한다. 앞으로 데이터를 주고 받을 때, 이 session key를 사용할 것이다.

[client, server] session 진행

세션이 열려있는 동안 client와 server는 데이터를 주고 받는다. 이 때, session key를 활용하는데 대칭키 방식이기 때문에 빠르게 통신할 수 있다. SSL/TLS의 과정을 보면 결국 대칭키를 안전하게 주고 받기 위해 공개키 방식을 사용하는 것인데, 왜 이렇게 하는 것일까? 공개키 방식은 리소스가 많이 들어가기 때문에, 많은 client와 통신하기에는 server가 부담스럽기 때문에 대칭키 방식을 사용해야 하기 때문이다. 그렇다고, 대칭키를 사용하는데 key를 곧바로 주기에는 위험하기 때문에 이런 복잡한 과정을 통해 안전하게 대칭키를 주고 받는 것이다.

[client, server] session 종료

데이터 전송이 끝났으면 client와 server는 서로에게 SSL 통신이 끝났음을 말한다. 이후, 세션키를 폐기한다.

정리

이렇게 SSL/TLS 프로토콜의 진행 과정과, 이해를 위해 필요한 용어들에 대해 알아보았다. “TLS 1.2 버전 쓰세요!”는 Application Layer에서 설정하는 것이니 파이썬 requests 모듈과 관련된 내용이라는 것도 알게 되었다. SSL/TLS의 핵심은 인증서에 있고, 인증서는 CA에서 발급(=구매)하는 것이고, 인증서에 있는 서버의 public key를 활용해서 session key(=대칭키)를 암호화 해서 전달한다는 것도 알았다!

여담

SSL/TLS에서 hello(=handshake) 하는 과정이 있는데, TCP의 3-way handshaking과는 다른 것인지 궁금해졌다. 결론적으로 말하면, 다른 것이다. TCP의 3-way handshaking은 Transport Layer에서 네트워크 연결을 설정할 때 사용되는 것이고, SYN, SYN-ACK, ACK를 통해 client와 server의 연결을 구성하는 것이다. SSL/TLS의 핸드셰이크는 보안 연결을 위한 것이다. 즉, “네트워크 연결”을 위한 것인지, “보안 연결”을 위한 것인지로도 구분이 되고, 애초에 네트워크 모델에서의 계층이 다르다는게 큰 차이점이었다.

참고 자료