HTTPS의 동작 원리에 대해 알아봅시다!
🔑 안전하게 메시지를 주고받기 위한 대칭키
한 쪽에서 다른 쪽으로 안전하게 메시지를 전달하는 방법은 무엇이 있을까요?
중간에 메시지를 탈취당하더라도 발신자와 수신자만 알아볼 수 있고
탈취되더라도 내용이 유출되지 않을 수 있는 방법이요.
대칭키 방식을 이용하면 될 것 같아요!
위와 같이 g는 11로, o는 22로 표기하기로 약속했다면,
go 라는 메시지를 전하기 위해 1122 라고 전달하면 되는 겁니다.
그러면 중간에 탈취당하더라도 다른 사람들은 1122가 무슨 의미인지 알 수 없겠죠?
g가 11, o가 22에 해당한다는 저 약속이 유출되지 않는다면
안전하게 메시지를 주고 받을 수 있을 것 같아요!
이렇게 전송 시점의 암호화, 수신 시점의 복호화에
같은 키를 사용하는 것을 대칭키 암호화 알고리즘 이라고 합니다.
웹 상에서 클라이언트가 서버가 통신할 때도
이렇게 대칭키 방식으로 통신하면 안전하게 데이터를 주고받을 수 있겠군요~
🤷♂️ 저는 대칭키가 아직 없는데요?
그런데 만약 위에서 말한 11 for g, o for 22 라는 대칭키 암호화 알고리즘이
양 당사자에게 아직 공유되기 이전이라면 어떨까요?
"야야, 우리 이제부터 11은 g라고 하고 22는 o라고 하자!"
라는 메시지를 보내야할 텐데, 이 메시지가 전송중에 탈취되면 어떻게 하죠?
이 대칭키가 만약 탈취된다면 이후의 모든 통신은 유출 위험에 놓였다고 봐야할 겁니다.
외부에 유출되어버린 대칭키로는 암호화를 해서 전송하더라도
같은 대칭키를 가진 악의적인 제3자가 복호화하여 이를 악용할 수 있기 때문입니다.
그럼.. 어쩌죠?;
🗝️🔑비대칭키 (공개키와 개인키)
앞서 대칭키를 암호화, 복호화에 같은 키를 사용하는 암호화 알고리즘이라 이야기했는데요,
이와 달리, 암호화, 복호화 시점에 다른 키를 사용하는 암호화 알고리즘을 비대칭키 암호화 알고리즘이라 합니다.
비대칭키 방식은 암복호화 시점에 서로 다른 키를 사용하기 때문에,
두 개의 키가 사용되는 건데요, 이 두 개의 키를 각각 공개키, 개인키 라고 이야기합니다.
그래서 공개키 암호화 방식이라고도 부릅니다.
그래서 공개키 방식이던 비대칭키 방식이던 그게 뭐냐?!
공개키로 암호화했다면, 개인키로만 복호화할 수 있습니다.
개인키로 암호화했다면, 공개키로만 복호화할 수 있습니다.
두 개의 키가 짝을 이루어 하나의 키로 암호화 된 데이터는 다른 키로만 복호화할 수 있는 구조입니다.
그림으로 살펴볼까요?
리차드 라는 서버는 자신의 공개키를 공개해둡니다.
자신에게 메시지를 보내기 원한다면, 나의 공개키로 암호화해서 보내세요~ 라는 목적으로 말이죠.
Client A와 Client B는 각각 리차드의 공개키로 메시지를 암호화해서 전송합니다.
리차드의 공개키로 암호화된 메시지는 리차드의 개인키로만 복호화가 가능합니다.
따라서 다른 누군가가 중간에 메시지를 탈취하더라도 이를 복호화할 수 없는, 안전한 상태가 가능해집니다.
오 그러면 공개키가 짱짱맨이군요!
드디어 클라이언트가 서버에게 안전하게 데이터를 전송할 수 있는 방법을 찾은 것 같아요!
그럼 이제 이걸로 통신하면 될까요?!!
비대칭키 방식의 한계 - 절반의 보안과 신뢰도
대칭키 방식의 한계를 극복하기 위해 비대칭키 방식을 사용하더라도 여전히 문제가 남아있습니다.
첫번째로 공개키를 가진 클라이언트가 암호화 해서 서버에게 전송할 땐 괜찮지만,
서버가 응답하는 데이터는 안전하게 암호화해서 전송할 수 없다는 점입니다.
개인키로 암호화를 한다면, 공개키로만 복호화가 가능한데, 공개키는 누구나 알고 있어요!
그러면.. 서버측의 응답은 안전하지 않은 상태가 되겠군요 ;ㅅ;
암호화(?) 되어있지만 누구나 복호화할 수 있기 때문이에요.
두번째로 상대방에 대한 신뢰의 문제예요.
대칭키 방식은 탈취되더라도, 잘못된 상대방에게 데이터가 전달되었더라도,
키가 없다면 복호화할 수 없기 때문에 수신 대상이 신뢰할만한지 여부가 큰 문제가 되지 않습니다.
(키를 탈취당하지 않는다면요!)
그러나 비대칭키 방식에선, 내가 메시지를 전송하려는 당사자, 수신자의 공개키로
데이터를 암호화해서 전송하기 때문에 수신자는 반드시 나의 데이터를 복호화할 수 있게 됩니다.
따라서 민감한 정보를 잘못된 대상의 공개키로 암호화해서 대상에게 전송한다면,
나의 민감한 정보가 고스란히 탈취당하는 겁니다.
따라서 이 사이트가 정말 신뢰할만한 사이트인지,
나의 개인정보를 이 사이트의 공개키로 암호화해서 전송해줘도 괜찮은 사이트인지 검증해야할 것 같아요.
신뢰할 수 있는 사이트인지 검증해주는 CA
우선 내가 접속한 사이트를 어떻게 신뢰할 수 있느냐의 문제를 먼저 접근해볼게요.
브라우저가 특정 사이트에 접속하고자 할 때,
서버는 응답으로 자신의 인증서를 보내줍니다.
자신이 신뢰할만한 사이트로 인증받았다는 증표에 해당하는 것인데요,
클라이언트는 브라우저는 내장되어있는 CA 들의 정보를 이용해서 인증서를 확인합니다.
보다 정확히는 CA의 공개키로 인증서를 복호화시도하는 겁니다.
그렇다면 이 인증서는 CA의 개인키로 암호화되었다는 의미겠죠?
사이트들은 자신이 신뢰할만한 사이트라는 인증을 CA로부터 받고 인증서를 발급받는데,
이때 발급받는 인증서가 CA의 개인키로 암호화되어 발급됩니다.
브라우저에는 CA들의 정보와 공개키가 내장되어있고,
서버로부터 받은 인증서를 CA의 공개키로 복호화하는데 성공했다면,
이는 CA로부터 인증된 신뢰할만한 사이트라는 걸 확인하는 데 성공했다는 의미입니다!
CA 는 Certificate Authority 의 약자로 인증기관이라는 의미입니다.
그럼 신뢰성의 문제가 해결되었으니,
마지막으로 서버는 어떻게 안전한 응답을 보낼 수 있는지 알아보겠습니다!
대칭키 세팅을 위한 비대칭키 방식의 활용
최초에 안전하게 메시지를 주고 받기 위한 방법으로 대칭키 방식을 소개했고요,
비대칭키 방식을 이용해 클라이언트가 서버에게 안전하게 메시지를 전달할 수 있는 방법을 소개했습니다.
또한 비대칭키 방식의 한계인 신뢰의 문제를 CA라는 제3자를 이용해 극복하는 방법도 소개했습니다.
그럼 이제 이 방법들을 활용해서 드디어! 안전하게 메시지를 주고 받아봅시다!
최종적으로는 대칭키를 클라이언트와 서버가 모두 들고 있게 될 겁니다.
그리고 이 대칭키를 이용해 서로간의 암복호화를 진행하며 안전하게 데이터를 주고 받게 될 거에요.
그러면 어떻게 대칭키를 클라이언트와 서버 모두
안전하게 들고 있는 상태까지 진입할 것이냐, 이 문제로 다시 돌아오게 됩니다.
대칭키를 전송하는 과정에서 탈취될 가능성에 대한 이야기인 거죠.
바로 이 지점에서 비대칭키를 사용하는 겁니다.
클라이언트는 서버의 공개키를 이용해 안전하게 서버에게 데이터를 전송할 수 있으니,
클라이언트가 비대칭키 방식을 이용해 대칭키를 암호화해 서버에 전송하면 될 것 같아요!
서버의 공개키를 얻는 방법에 대해 앞서 소개하지 않았는데요,
서버측에서 자신이 신뢰할만한 사이트라며 응답해온 인증서를 복호화하면
그 안에 서버의 공개키가 포함되어 있습니다.
이 공개키를 이용해서 대칭키를 전송하면 될 것 같아요!
약간의 디테일을 더하자면
지금까지 논의한 내용을 정리해보자면 다음과 같습니다.
대칭키 방식으로 암복호화하며 데이터를 주고받는다면 안전하다.
다만 대칭키를 양쪽이 모두 안전하게 가지고 있는 상태에 도달하기 위해 비대칭키 방식이 필요하다.
서버의 공개키로 암호화해서 전송한다면 클라이언트의 전송은 안전하게 된다.
서버가 내 정보를 보내도 되는 신뢰할만한 사이트인지에 대해 확인하기 위해 CA 역할이 필요하다.
서버는 CA의 개인키로 암호화된 자신의 인증서를 응답해주고 브라우저는 이를 CA 공개키로 복호화한다.
복호화 결과로 나온 서버의 공개키로 대칭키를 암호화해서 전달한다.
이후로는 안전하게 대칭키로 데이터를 주고받는다.
큰 틀에서 보자면 위의 내용 정도를 이해하는 것으로도 HTTPS의 흐름을 충분히 이해했다고 생각하지만,
약간의 디테일을 더한다면 아래의 내용을 덧붙일 수 있을 것 같습니다.
Client Hello
클라이언트 생성 랜덤 데이터 및 클라이언트 지원 암호화 방식 전달
Server Hello
서버 생성 랜덤 데이터, 서버가 선택한 암호화 방식, 인증서 전달
인증서 확인
브라우저 내장 CA 공개키로 인증서를 복호화 시도
복호화 성공 시 신뢰할 만한 사이트라고 확신
복호화 결과로 얻은 서버의 공개키 획득
pre master secret 생성
클라이언트가 수행
클라, 서버측의 랜덤 데이터를 조합하여 pre master secret 생성
서버로 전송하기 전에 서버의 공개키로 암호화
학습 후기
매 세션마다 새로운 대칭키를 생성해야 하기 때문에
handshake 과정에서 서버와 클라이언트가 생성한 난수를 조합하여
대칭키를 생성하는 과정이 신기했습니다.
브라우저에 내장된 CA의 신뢰도를 기반으로 하여
다른 사이트에 대한 신뢰도를 평가하기 때문에,
신뢰할 수 있는 브라우저를 사용하는 것부터가 중요한 첫 단추가 될 것 같습니다.
가령 엄한 브라우저를 사용하면, 잘못된 CA 목록이 들어있어서
악의적인 사이트를 안전하다고 사용자에게 보여줄 수도 있을테니까요.
추가로 CA가 인증서를 발급하는 과정에서 어떤 부분을 검증하는지 궁금하네요.
certbot이나 cloudflare 등의 서비스만 이용해보았더니
어떤 검증 절차에 의해 인증을 해주는 것인지 잘 모르겠네요.
마지막으로 CA들은 누가 인증해주고 관리감독할지 궁금하네요.
TCP/IP 위에 SSL이 있고 그 위에 HTTP, FTP가 있어서,
같은 절차를 진행하면 FTP도 안전한 SFTP가 되는 방식이었다는 걸 처음 알았습니다! :)
학습 출처
HTTPS가 뭐고 왜 쓰나요? (Feat. 대칭키 vs. 비대칭키)
찬, 칙촉과의 말하기 스터디
'Server & Infra' 카테고리의 다른 글
Jenkins, Multibranch-pipeline을 이용한 CD (0) | 2022.09.10 |
---|---|
Git에 잘못 올린 파일 삭제하기 (0) | 2022.08.29 |
SonarQube with Github Actions (PR Decoration) (0) | 2022.08.17 |
t4g 인스턴스와 ARM 아키텍처 (0) | 2022.08.16 |
Jacoco with Github Action (0) | 2022.08.08 |