이전 포스트에서 프로토콜중 http 와 https에 관하여 간단히 알아봤었다. 오늘은 그중 https, 정확히는 보안을 어떤식으로 하는지 간단히 알아보려 한다.
http는 이름에서도 볼수 있듯이, 텍스트 데이터를 주고 받는다. https는 이 텍스트 데이터를 SSL 이나 TLS 프로토콜을 한번 거쳐 암호화를 한뒤 이용한다. 보안의 수준은 웹브라우저 에서의 구현정확도와 서버 소프트웨어, 암호화 알고리즘에 따라서 천차 만별이라고 한다. 여담으로 SSL이 확산되다가 국제표준기구인 IETF로 넘어가면서 TLS로 이름이 바뀌었다고 한다. 둘이 같은거라고 봐도 무방할듯 싶다.
SSL / TLS
둘이 같은거라고 봐도 무방하기 때문에 이후 SSL로 통합해서 이야기 하겠다. SSL또한 프로토콜의 일종이다. Secure Sockets Layer의 약자로 데이터를 안전하게 전송하기 위한 통신 규약(프로토콜) 이다. 사실 SSL은 HTTPS 만을 위한게 아니다. 원격에 있는 파일을 주고받는데 사용되는 프로토콜인 FTP에 SSL이 더해지면 SFTP가 되듯이, 결국 보안을 위한 독립적인 역할을 해준다. 각설하고 SSL이 어떤식으로 데이터를 암호화 하는지 보도록 하겠다. 참고로 암호화 알고리즘이 아닌, 암호화 방식에 관하여 알아볼 것이다.
첫번째로 대칭키 방식이다. 키(key)라고 하면, 데이터를 암호화 하는데 사용되는 비밀번호라고 생각하면 된다. 첫음 암호화 하는데 사용된 키와 동일한 키로 복호화(암호를 푸는 것) 하는것을 같은 키를 사용(대칭)한다 하여 대칭키라고 부른다. 즉, 암호화를 0000 으로 했다면 복호화 또한 0000 으로 하게 된다. 음… 그런데 이것은 조금 위험하지 않을까? 배포할때 결국 키도 같이 배포해야 하는데, 암호화 하는 키가 배포하려던 사람 이외에도 노출이 되면… 으 상상을 하지 말자.
두번째로 알아볼게 공개키 방식이다. 대칭키가 암호화 키와 복호화 키가 같았다는것과는 다르게 공개키 방식은 암호화 키와 복호화키가 서로 다르다. 여기서 암호화 키를 개인키(Private key), 복호화 하기 위하여 제공하는 키를 공개키(Public key)라고 한다. 방식은 A 라는 키로 암호화 한것은 B키로 복호화 하고, B키로 암호화 한것은 A키로 복호화 하는 식으로 운용된다. 디지털 인증서에는 공개키로 이용될 키를 함께 배포한다.
이 설명을 보고 “음? 뭐야 결국 공개키도 노출 되면 위험한거는 마찬가지 아님?” 이라고 생각할수 있다. 위험한 포인트가 다르다. 키 자체가 노출되는게 문제가 아니라, 이 키를 이용하여 엉뚱한 데이터를 암호화 해서 배포하면 위험하다는 것이다. 예를 들어 바이러스같은걸 암호화 해서 배포해서 복호화 하여 사용하면… 이게 제작자가 배포한건지 제 3자가 뿌린건지 모른다. 즉, 공개키 방식은 암호화 뿐 아니라 데이터 제공자의 신분도 보장해주는 것이다. 공개키를 이용해 복호화 했다는 것은 제작자만 가지고 있는 개인키로 암호화를 했다는 것이니까 말이다.
SSL 인증서
위에서 데이터 제공자의 신분을 보장한다는 말을 했다. 이 신분을 보장해주는게 디지털 서명이다. 이 디지털 서명은 서비스 제공업체와는 다른 서드파티 기업인 CA 기업들이 해준다. CA(Certificate Authority) 혹은 Root Certificate 이라고도 하며 디지털 인증서를 제공하는 보증된 기업들을 말한다.
[출처 : 초코몽키의 개발로그, https://wayhome25.github.io/cs/2018/03/11/ssl-https/]
위는 디지털 인증서의 동작방식의 예시이다. 결국 CA 기업중 하나에서 인증서를 사서 배포해야 한다는 것이다. 이러한 CA사들은 브라우저들이 이미 알고 있어 보증을 해준다.(물론 인증된 CA 사들이다.)
[출처 : 12bme 개발로그, https://12bme.tistory.com/80]
인증안된 ssl 인증서를 사용하면 위 이미지 처럼 x 표시가 뜬다. 가끔 특정 웹페이지에 접근할때 인증되지 않은 사이트이라느니 위험할수 있다느니, 분명 https 사이트인데도 뜨는곳은 위와 같은 이유이다. 브라우저가 해당 인증서를 배포한 회사를 몰라서…
SSL 동작 방식
SSL이 동작하는 방식은 Handshake -> Session -> Session end 의 과정을 거친다.
1. Handshake
[출처 : 12bme 개발로그, https://12bme.tistory.com/80]
우리 말로 악수이다. 악수를 하는 주 목적이 무엇인가? 인사이다. 서로가 존재하는지 확인하는 과정이다. 데이터를 주고 받을때도 마찬가지이다. 주는쪽이나 받는쪽이 존재하지 않겠는가. 그리고 데이터를 주고받을때 어떤방식을 이용할지를 확인하는 과정이기도 하다. 서버와 클라이언트가 서로 다른 암호화 방식을 사용할수도 있기 때문에 서로 알려준다. 이때 클라이언트쪽에서 알려주는걸 ‘Client Hello’, 서버측에서 알려주는걸 ‘Sever Hello’ 라고 한다. 이름참 재밌네.
Client Hello에 관한 응답으로 Sever Hello가 오게 되고, 클라이언트쪽에서 전달받은 암호화 방식중 서버는 자신이 사용할 수 있는 방식을 답해줌으로써 어떤 암호화 방식을 사용할지 협상하는 과정이라고 볼수 있다.
이렇게 암호화 방식을 교환하고 나면, 클라이언트는 서버를 신뢰 할수있는지 판단한다. 클라이언트 내부의 공개키를 이용하여 CA사의 인증서를 복호화 하려는 시도를 하고, 복호화에 성공하면 서버를 신뢰할수 있게 된다. 이때 받은 랜덤 데이터와 클라이언트 내부의 랜덤데이터를 조합해 pre master secret 이라는 키를 만든다. 그리고 이키를 클라이언트는 배포받은 공개키로 암호화해 서버에 보내며, 서버는 가지고있는 개인키로 복호화 한다. 이로써 pre master secret 키를 서버와 클라이언트 모두 공유하게 됨으로써 서로를 신뢰하고 데이터를 주고받기 위한 Handshake가 끝이난다.
2. Session
실제로 데이터를 주고받는 단계이다. 참고로 이때 데이터를 주고받을 때는 공개키 방식이 아닌 대칭키 방식을 사용한다고 한다. 이는 공개키 방식 자체가 부하를 많이 줘서라고 한다. 많은 사람이 접속하는 서버쪽에서 이러한 부하는 큰 부담이 될수 있기 때문에, 서로를 확인하는 과정에서는 공개키로 하고 이후 보장된 사이에서는 대칭키로 간단하게 암호화를 해서 통신한다고 한다. 이러한 대칭키를 session key 라고 한다. 이 session key는 이전 Handshake에서 만들어진 pre master secret 키를 master key 로 전환하에 생성한다고 한다.
3. Session end
모든 과정의 종료 부분이다. 이 과정에서 session key를 폐기한다.
서로 인식하고, 사용할 암호를 전달하고, 데이터 전송하고, 볼일끝나면 서로에 대한 정보를 파기하는 참으로 깔끔한 관계가 아닐까 싶다.