SSL과 HTTPS에 대한 이해

웹서버가 https로 통신하는 것은 생각보다 매우 복잡하고 견고한 기술들로 이루어져 있다. 인증서를 발급받고 웹서버에 적용하는 것은 간단하지만 이 과정을 정확히 이해하지 않았을 때에는 SSL과 관련한 문제를 해결하는게 굉장히 어렵다. 웹서버를 운영한지 1년정도가 흐른 지금에서야 이 과정을 어렴풋이 설명할 만큼 이해하게 되었다. 이번 글은 생활코딩의 HTTPS와 SSL 인증서를 통해 공부하고 이해한 내용을 바탕으로 정리해보았다. 또, 버즈빌의 개발 이야기 앞부분에서도 쉽게 설명되어있다(뒷부분은 암호화에 대한 디테일한 설명이 있다).

SSL과 인증서

SSL과 인증서는 다르다. SSL(Secure Socket Security), TLS(Transport Layer Security)는 컴퓨터 네트워크 통신에 보안을 제공하기 위한 암호 규약이고, 인증서는 클라이언트에게 안전한 웹서버임을 ‘증명’해주는 수단이다.
참고로 SSL은 취약점이 많이 발견되어서 요즘은 TLS통신을 한다. SSL은 TLS의 구 버전이라고 생각하면 된다(SSL vs TLS)

안전한 웹서버라면 아래와 같이 보안의 3요소를 갖추고 있어야 한다. 비단 웹서버에만 속하는 사항은 아니다.

  1. [인증성, Authenticity] 검증된 제 3자에 의해 신뢰할 수 있다는 것이 보장되어야 한다.
  2. [비밀성, Confidentiality] 신뢰할 수 있는 웹서버에게 보낼 데이터는 누군가 훔쳐보지 못하도록 암호화 되어야 한다.
  3. [무결성, Integrity] 암호화된 메시지는 누군가 변경하지 않도록 해야 한다.


SSL과 인증서는 동일한 개념은 아니지만, 웹서버가 위의 보안의 세 가지 요소를 갖출 수 있도록 견고하고 밀접하게 구성되어있다. 인증서 1. 가용성을 보장해주며, 인증서 안에는 웹서버가 2. 비밀성, 3. 무결성을 위한 SSL통신을 할 수 있도록 key가 있다.

그래서 https를 이해하려면 인증서SSL 통신에 관한 이해가 각각 필요하다. 그리고 인증서와 SSL통신은 암호화를 바탕으로 하기 때문에, 대표적인 암호화 방식인 대칭키 방식과 공개키방식에 대해 기본적으로 알고 있어야 한다.

인증서 동작 방식

인증서에는 ‘공개키’ 알고리즘이 사용된다.

Client = Browser = Everyone는 제 3자인 검증된 인증기관의 ‘공개키’를 갖고 있다. 공개키는 아무나 갖게될 수 있다. 인증 기관은 인증을 요청한 웹서버에게 자신의 ‘비밀키’로 암호화된 인증서를 제공한다. 클라이언트가 요청을 보내면 웹서버는 인증기관에게 받은 암호화된 인증서를 클라이언트에게 제공하고, 클라이언트는 이를 자신이 갖고 있던 ‘공개키’로 복호화하여 신뢰할 수 있는 웹서버인지 확인한다. 복호화가 성공했다면 이 인증서는 올바른 비공개키 = 인증기관 자신의 비공개키로 암호화 되었다는 의미이다. 클라이언트가 갖고 있는 인증기관의 공개키로 복호화가 되지 않는다는 것은, 인증서가 인증기관의 비공개키로 암호화되지 않았다는 것이다. 즉, 인증서를 신뢰할 수 없기 때문에 웹서버도 신뢰할 수 없게 된다.
-> 이 과정은 보안의 3요소 중 ‘가용성’을 만족시킨다.

SSL 동작 방식

SSL은 ‘공개키’와 ‘대칭키’ 알고리즘이 결합되어 있다.

인증서를 통해 이제 클라이언트는 이 웹서버를 신뢰하게 되었다. 다음 단계로는 웹서버까지 클라이언트의 데이터를 안전하게 배송시켜야 한다. 데이터를 누군가 훔쳐보지 못하도록(비밀성), 그리고 중간에 변경되지 않도록(무결성) 암호화 해야한다. 이를 위해 클라이언트와 서버는 데이터를 암호화하여 주고받는데, 이 때에 사용되는 방식은 ‘대칭키’ 방식이다.
그런데, 대칭키 방식을 위해 대칭키를 그냥 주고받기에는 위험하다. 암호화와 복호화에 사용되는 키가 하나이기 때문에 이 대칭키를 알기만 하면 당사자인 웹서버가 아닌 아무나 복호화할 수 있기 때문이다. 그래서 더 이상적인 방법은 ‘대칭키’가 아닌 ‘공개키’ 방식으로 암호화하는 것인데, 이 방식은 데이터 암복호화에 걸리는 시간이 너무 오래걸린다.
-> 결론적으로 웹서버는 실제 데이터는 대칭키방식으로, 대칭키는 공개키방식으로 한 번 더 암호화한 후 공유하는 방법을 채택하게 된다. 실제로 SSL이 동작하는 과정은 아래와 가이 몇 단계로 이루어져있다. 처음에는 Client와 Server가 통신을 약속하고 세션 키를 생성하는 Handshake 과정이 일어나는데, 이미 세션이 있다면 Handshake과정은 생략된다.
1) Client Hello

2) Server Hello

3) 세션

4) 세션 종료

데이터의 송수신이 끝나면 SSL 통신이 끝났음을 알려주고, 통신에서 사용한 대칭키인 세션키는 폐기한다. 이 과정은 제 3자가 대칭키인 세션키를 탈취하기에는 매우 짧은 시간이 일어난다. 즉, 세션키는 단시간 사용되고 폐기된다.

SSL과 인증서는 위와 같이 매우 복잡하고 견고한 과정으로 구성되어 있다. 관심이 없거나 잘 모르면 그림을 봐도 잘 이해가 가지 않는 과정이기 때문에 그림하나 없이 길고 장황하게 글로 나열했다. 실제로 패킷을 잡아서 이 과정을 눈으로 확인하는 과정에 대해 설명한 ‘The First Few Milliseconds of an HTTPS Connection’와 같은 글도 있다. 한 번 읽어보고 따라해보면 더 기억에 오래남을 것 같다.

그리고 인증서/SSL에 대해서 공부하며 느낀점은 인증서는 순전히 client를 위한 보안이라는 것이다. 클라이언트는 웹서버가 신뢰할 수 있는 웹서버인지 검증할 수 있지만, 웹서버는 지금 요청을 보낸 클라이언트가 신뢰할 수 있는지 검증할 수 없다. 이것은 단방향 안전인 것인가? 우리=웹서버는 클라이언트의 공격으로부터 안전해야 한다. 이런 점들에 대해서도 추가적으로 알아볼 필요가 있어보인다.