NERD WORLD

SSL/TLS 본문

토막지식

SSL/TLS

학부생7년차 2016. 4. 29. 01:05

계기: 위즈네트 4월 아카데미 강의들 중 "Facebook을 통한 디바이스 컨트롤 (SSL, RTOS, HTTP를 한방에)" 강좌가 있었다. IoT 시스템을 구현하려면 보안이 중요하니 SSL/TLS를 필히 구현해야한다. 강사님께서 이를 위해 2개월간 C언어로 SSL/TLS 부분을 수행하는 코드를 작성하셨고, 이를 활용해서 진행된 수업이었다. 웹에서 보안에 대한 이슈들은 문외한이었으므로 이번 기회에 정리해보고 싶었다.


주의사항: 작성자가 창작하 지식은 하나도 없음. 아래 참고에 적은 두개의 링크에 기술된 지식을 이해하고, 이해를 다질겸 간단히 정리해본것에 불과함.




대칭키(symmetric key)

P라는 키(key)로 암호화하면, 그 P로 복호화하는 기법이다. 이때 이 암호화/복호화에 둘 다 쓰이는 키를 대칭키라고 한다.


공개키/비밀키(public key/private key)

대칭키 방법은 단순하지만, 실제 써먹기가 어렵다. 대칭키를 서로 통신하고자 하는 주체들만 알고 있어야 하는데, 이 대칭키를 누군가에게 알려주기 위해서는 또 암호화된 통신이 필요하다(?) 닭이 먼저냐 계란이 먼저냐 하는 셈이다. 이를 해결하기 위한 방법이 공개키/비밀키 방법이다. 공개키로 암호화하면 비밀키로 복호화할 수 있고, 반대로 비밀키로 암호화하면 공개키로 복호화할 수 있다. 두 가지 실제 응용이 가능하다.


1) 비밀 정보 받기: 공개키는 이름 그대로 공개해버리고, 비밀키는 나만 간직하고 있는다. 내게 비밀 정보를 건네고 싶은 누군가가 공개키로 암호화해서 내게 전달하면, 나는 비밀키로 복호화해서 그 내용을 볼 수 있다. 비밀키를 가진 사람은 나뿐이므로 다른 사람은 복호화할 수 없다.


2) 전자 서명: 어떤 정보를 남들에게 공개하고 싶을때, 이 정보를 "내가" 생성했음을 인증할 수 있다. 공개하고 싶은 정보 M과 이를 내 비밀키로 복호화한 M'을 동시에 전달한다. 그러면 이 정보를 본 다른 사람은 공개키로 M'을 복호화해서 M과 동일한지 확인한다. 동일하지 않다면 내가 아닌 다른 사람이 나를 사칭한 것으로 간주할 수 있다.


인증기관(CA)과 인증서(Certificate)

드디어 SSL/TLS의 본론으로 넘어왔다. 서버와 클라이언트가 SSL/TLS 프로토콜로 본격적인 통신을 시작하기에 앞서, 핸드-쉐이킹 작업이 이뤄진다. 자세한 내용은 건너뛰겠다. 핸드-쉐이킹 작업 중 중요한 한 가지는, 서버가 자신의 인증서를 클라이언트에게 보내는 작업이다. 클라이언트는 받은 인증서를 확인해서 정말로 이 서버가 믿을만한 서버인지 검증하는 작업이다. 어떻게 이 작업이 이뤄질 수 있을까?

이를 위해 서버와 클라이언트 외에 제 3자인 인증기관(CA, Certificate Authority)이 등장한다. CA는 인증서를 신청한 서버를 직접적으로 검증해서 서버가 제공하는 서비스와, 서버를 운영하는 주체가 믿을만하다고 판단이 되면 인증서를 발급해주는 기관이다. 이때 공개키/비밀키 방식이 쓰인다. CA는 서버 운영 주체가 제출한 인증서를 자신의 비밀키로 암호화해서 돌려준다. 그 인증서를 서버가 가지고 있으면서, 클라이언트에게 전해주는 것이다. 보통 웹 통신을 위해서 클라이언트는 웹 브라우저를 사용한다. 이 브라우저는 이미 믿을만한 CA들과, 그 CA들의 공개키를 가지고 있다. 그러므로 서버가 자신의 인증서와, 인증서를 인증한 CA를 알려주면 클라이언트는 그 CA의 공개키를 사용해서 인증서를 복호화해서 실제 그 서버와 일치하는지 확인한다. 잘 확인되면, 그 서버는 검증된 것이다.


서버와 클라이언트 사이의 통신

이제 서버가 믿을만한 서버인지는 확인되었다. 본격적으로 암호화된 통신을 하고 싶을 것이다. 배운 지식을 활용해보자면, 서버가 자신의 공개키를 알리고 클라이언트도 자신의 공개키를 알린 뒤에 서로 공개키/비밀키 기법을 써서 암호화된 통신을 하면 모든 문제가 해결될 것만 같다! 하지만 문제가 있다. 공개키/비밀키 기법을 사용해서 통신을 하기 시작하면 암호화/복호화의 오버헤드가 커서 통신이 느려진다....

그러므로 대칭키 기법을 사용해서 통신을 한다! 엥? 그런데 이상하다. 대칭키 기법은 그 대칭키를 주고받을 방법이 없으므로 실제 써먹을 수가 없어보였기 때문이다. 이 지점에서 아름다운 조화가 이뤄진다. 서버와 클라이언트가 공동으로 사용할 이 대칭키를 공개키/비밀키 방식으로 주고 받는다.

간단히 설명하면 이러하다. 서버는 비밀키를 가지고 있고, 클라이언트에게 인증서를 보낼때 공개키를 함께 보낸다. 클라이언트는 어떠한 방식으로 굉장히 랜덤한 데이터(pre-master secret)를 생성해서 서버의 공개키로 암호화해서 서버에게 보낸다. 서버는 비밀키로 복호화해서 클라이언트가 보낸 pre-master secret을 얻어낼 수 있다. 그 뒤에 둘이 서로 약속한 변환을 적용해서 pre-master secret을 master-secret으로 변환하고, 이 master-secret이 이후의 암호화된 통신에서 사용할 대칭키가 되는 것이다! 참으로 아름답다.


여기까지만 정리해보도록 하자.




참고:


[1] 생활코딩의 "HTTPS와 SSL 인증서" 강의: 마지막 pre-master secret 부분을 제외한 모든 내용은 이 강의의 내용을 이해한 뒤 정리한 것에 불과함.

[2] TLS 나무위키: pre-master secret 부분이 [1]에서 이해가 막혀, 나무위키의 내용을 참고함.


'토막지식' 카테고리의 다른 글

Authentication과 Authorization  (0) 2016.07.01
AWS EC2에 보유중인 도메인 지정하기  (0) 2016.06.17
Python, Encapsulation  (2) 2016.06.16
NAT와 포트-포워딩(Port-Forwarding)  (1) 2016.04.22
공인 IP와 사설 IP  (0) 2016.04.22
Comments