HTTP/HTTPS
http
는 OSI 7계층에서 어플리케이션 계층 프로토콜에 해당하며 클라이언트-서버 간 단방향, 비연결성 통신을 한다. 즉 웹 브라우저에서 CRUD에 대한 요청을 보내야지만 서버에서 그에 대해 응답하는 형태이다.
여기서 중요한 점은 요청과 응답 과정에서 전달되는 정보가 암호화 되어있지 않다는 점이다. 이를 통해 중간자 공격(Man-in-the-middle-attack)을 통해 데이터를 가로챌 수 있는 가능성이 열리게 된다.
https
는 끝자리에 secure가 들어간 것으로 서버와 브라우저 간 암호화된 연결을 생성한다. 여기서 암호화되어 전달되는 데이터는 http message body에 해당한다.
https의 암호화는 SSL/TLS 통신을 기반으로 이루어 진다.
SSL/TLS
SSL은 1990년대에 도입된 웹 보완 프로토콜이며 3.0 버전에서 보안의 취약성이 발견되어 이를 개선한 버전으로 TLS가 등장하게 되었다. 그래서 현재 사용되는 프로토콜은 TLS에 해당하며 인증 기관에서 SSL이라는 명칭을 언급하더라도 내부적으로는 TLS 방식을 채택하고 있다고 볼 수 있다.
SSL 통신 방법
기본적으로 클라이언트-서버 간 동일한 대칭키를 기반으로 message body를 암호화하여 통신한다. 하지만 그 전에 같은 대칭키가 서로 공유되어야 하는데 아래와 같은 방법으로 클라이언트가 서버에게 대칭키를 전달한다.
- 클라이언트가 서버에게 접속 요청을 한다.
- 서버가 본인이 가진 공개키를 클라이언트에게 보낸다.
- 클라이언트는 대칭키를 신규 생성하여 서버에게 받은 공개키로 암호화하여 서버에게 전달한다.
- 서버는 암호키로 클라이언트에게 받은 데이터를 복호화하여 대칭키를 확보한다.
💡 대칭키/비대칭키
대칭키는 암호를 설정하거나 푸는 암호규칙(비밀키)과 같다. 규칙만 알고있다면 누구든지 정보를 암호화하거나 복호화할 수 있다. 그렇기 때문에 통신을 위해 원격으로 열쇠를 전해주는 방식 자체에 불안 요소가 있다.비대칭키는 공개키와 개인키로 구분하며, 자물쇠와 열쇠의 역할이 이와 같은 구조로 볼 수 있다. 만약 A가 B에게 정보 전달을 요청하는 상황이라면 A는 B에게 요청과 함께 좌물쇠(공개키)를 열린 상태로 보내준다. 그러면 B는 전달할 정보를 통에 담아 받은 좌물쇠로 잠근 뒤 A에게 보내게 되고, A는 해당 좌물쇠의 열쇠(개인키)로 통을 열어서 내부 정보를 확인하는 방식이다.
즉 공개키로 암호화된 정보는 비밀키로만 복호화가 가능하므로 단순히 공개키가 외부에 공개되는 것은 아무런 의미가 없다. 하지만 비밀키는 외부에 누설되지 않도록 철저히 본인만 보관할 필요가 있다.전자서명이 바로 이 비대칭키로 이루어지는데 이는 앞서 언급한 암호화/복호화 방식과는 차이가 있다. 전자서명의 용도는 데이터의 무결성 확보와 발신자의 인증에 있는데, 특정 메시지를 대상으로 A가 개인키를 활용하여 서명을 생성하면(암호화하면) B가 사전에 받은 공개키로 이를 검증할 수 있어 해당 서명이 A로부터 왔음(출처)을 신뢰할 수 있게 되는 방식이다. 또한 서명의 전달 과정에서 메시지 수정이 발생했다면 공개키로 검증이 통과되지 않을 것이고, 이러한 원리를 통해 무결성을 확보한다.
인증 기관을 통한 SSL 통신
클라이언트와 서버 사이의 통신에서 인증 기관이 개입하여 클라이언트로 하여금 서버가 신뢰할 수 있는 사이트라는 것을 보증한다. 이를 통해 클라이언트는 https 프로토콜을 사용하는 브라우저에 대한 신뢰를 갖게 된다.
인증기관 공개키 배포
- 모든 클라이언트는 기본적으로 인증 기관을 통해 인증 기관의 공개키를 받아둔다. 정확히 말하자면 기본적으로 브라우저 내부에는 여러 인증 기관의 ROOT CA 인증서가 자동으로 내장되도록 설정되어 있으며, 인증서 안에 공개키가 포함되어 있다.
서버의 인증서 등록
- 특정 서버가 특정 인증기관으로부터 사이트에 대한 신뢰성 검증을 받기 위해 사이트 정보와 사이트 공개키를 전달한다. (https 프로토콜 적용을 위함)
- 인증기관은 해당 사이트의 신뢰성 검증 후 인증 기관의 개인키로 사이트 정보와 사이트 공개키를 서명하여 인증서를 생성하고 서버에 전달한다. 여기서 서명한다는 의미는 ‘사이트 정보와 사이트 공개키’를 해시값으로 변환하여 개인키로 암호화하는 것을 의미한다. 그래서 결론적으로 원본 해시값(평문)과 서명을 함께 전달하게 되는데 이것이 ‘인증서’가 된다.
- 서버는 인증기관으로부터 받은 인증서를 서버에 보관한다.
클라이언트와 서버 간 통신
- 클라이언트가 서버에 접속 요청을 보내면 서버에서 인증서를 먼저 보낸다.
- 클라이언트는 보유한 인증 기관의 공개키로 인증서의 서명을 검증한다. 구체적으로 클라이언트는 인증서에 담긴 평문 데이터(사이트 정보, 사이트 공개키)에 해시함수를 적용한 원본 해시값으로 변환하고, 인증 기관의 공개키를 활용하여 서명에서 특정 해시값을 추출하게 되는데, 이 추출 결과가 원본 해시값과 일치할 경우 해당 인증서가 유효하다고 판단한다. 쉽게 말해 서명만 덜어내어 원본 데이터 해시값의 일치여부를 비교한다고 볼 수 있다.
- 인증서의 유효성이 검증되면 클라이언트에서 서버와의 통신에 사용될 대칭키를 생성하고, 사이트 공개키를 통해 암호화하여 서버에 전달한다. 이는 대칭키를 공유하기 위함이다.
- 서버에서 사이트 개인키를 통해 클라이언트로 받은 암호를 복호화하여 대칭키를 확보하게 된다.
- 이후 대칭키를 기반으로 요청/응답이 암호화되어 전달되고, 이는 세션이 만료될 때 까지 사용하므로 주로 세션 키 또는 세션 암호화 키로 불린다.
'백엔드 개발자(node.js)가 되는 과정' 카테고리의 다른 글
마이크로 서비스에 대해 간략히 살펴보기 (2) | 2023.12.01 |
---|---|
이벤트 기반 아키텍처(EDA) 살펴보기 (2) | 2023.11.21 |
AWS Cloudfront의 work flow 살펴보기 (0) | 2023.09.12 |
Nestjs passport로 카카오, 구글 로그인 인증 구현하기 (1) | 2023.09.06 |
python openCV로 OBS Virtual Camera 송출하기 (0) | 2023.09.05 |