[네트워크] HTTP 프로토콜 파헤치기 - HTTPS란 무엇일까?

들어가며...
인터넷을 사용하는 사람이라면 하루에도 브라우저 내의 웹페이지들을 이리저리 오가곤 한다.
이전의 포스팅 글 www.google.com을 접속하면 일어나는 일 을 보면 알겠지만
웹페이지들을 접속해서 이리저리 작업을 하는 과정들은 전부 네트워크를 통해 요청/응답이 이뤄지는 형태이다.
따라서, 누군가가 우리의 요청을 몰래 감시하며 요청에 대한 정보들을 이리저리 빼간다면 개인 정보 유출 및 개인 정보 보안에 크게 위협이 될 수 있다. 이러한 상황 때문에 보안 조치를 강화하고 안전한 통신을 하는 것은 매우 중요하다.
HTTP란 무엇인가?

하이퍼텍스트 전송 프로토콜(HTTP)란 월드 와이드 웹(WWW)의 토대이며, 하이퍼 텍스트 링크를 사용하여 웹 페이지를 로드하는 데에 사용된다. HTTP는 네트워크 장치 간에 정보를 전송하도록 설계된 어플리케이션 계층의 프로토콜이며 HTTP를 통한 일반적인 흐름에는 클라이언트 시스템에서 서버에 요청을 보내고 응답을 받는 작업이 포함된다.
이러한 HTTP 프로토콜은 정보를 전송 한다는 목적이 있기 때문에, 보안적으로는 고려가 되지 않은 프로토콜이다.
따라서, HTTP 프로토콜로 요청을 보내면 이러한 요청 메시지는 평문 그대로 메시지에 담겨서 요청이 날라간다는 특성이 있다.
이를 확인하기 위해서 간단하게 임시로 HTTP 서버를 열고 POST 요청을 보내보겠다.

다음과 같이 POSTMAN을 이용해 데이터와 함께 요청을 전송한다.

Wireshark 프로그램에서 패킷을 살펴본 결과 다음과 같이 원문 그대로 내용을 확인할 수 있다.
HTTPS란 무엇인가?

위에서 평문으로 그대로 요청 메시지가 보내진다면, 누군가가 요청 장소와 서버 사이 길목에 서서 해당 패킷을 낚아챈다면
쉽게 사용자의 정보를 확인하고 이를 악용할 수 있을 것이다.
이러한 점을 막기위해서 등장한 것이 HTTPS이다. HTTPS란 하이퍼텍스트 전송 프로토콜 보안 (Hypertext Transfer Protocol Secure)로 HTTP 전송에 보안 개념이 추가된 것이다. 데이터 전송의 보안을 강화하기 위해서 해당 HTTP 메시지 SSL/TLS 암호화 프로토콜을 이용해 암호화 한다.
이것도 위와 마찬가지로 Wireshark 로 패킷을 확인해보면

HTTPS를 사용하여 요청을 보냈을 때는 Encrypted Application Data로 데이터가 암호화된 것을 확인할 수 있다.
SSL/TLS 란?
SSL은 초기에 Netscape에 의해 개발되었고, 후에 TLS라는 이름으로 IETF의 공개 표준이 되었습니다. TLS는 SSL의 후속 버전으로, 보안성과 신뢰성이 향상되었다.
SSL/TLS의 주요 기능은 다음과 같다.
1. 암호화: 대칭키 암호화와 비대칭키 암호화를 혼합하여 데이터를 암호화한다. 이로인해 데이터 기밀성을 보장한다.
2. 인증: 디지털 인증서를 사용하여 서버 및 클라이언트의 신원을 확인한다. 인증 기관이 발급한 인증서를 통해 신뢰성을 확보한다.
3. 무결성: 메시지 인증 코드(MAC)를 사용하여 데이터 무결성을 보장하여 중간자 공격을 방지한다.
HTTPS 암호화 방식
그러면 HTTPS는 어떻게 안전하게 통신을 하기 위해서 암호화, 복호화를 수행한다는 것일까?

대칭키 암호화 방식
대칭키 암호화 방식은 하나의 암호화키(key)로 평문을 암호화하고, 마찬가지로 암호문을 평문으로 복호화할 수 있는 방식을 말한다.
송신자와 수신자 모두 동일한 키를 가지고 있어야 되며, 누구라도 암호화키를 탈취한다면 요청 및 응답을 복호화하여 볼 수 있다는 치명적인 단점이 있다.
공개키 암호화 방식
공캐키 암호화 방식은 공개키, 개인키 두 개의 키를 한 쌍으로 각각 암호화/복호화에 사용된다.
일반적으로 공개키로 암호화하고 개인키로 복호화를 한다.
이도 마찬가지로 중간자 공격에 매우 취약하지만 직접적으로 키를 교환하지 않고, 디지털 서명을 통한 인증 절차가 추가로 들어가서
대칭키 암호화보다 보안성이 높다고 볼 수 있다.
하지만 이러한 방식은 추가적인 절차가 많아지기 때문에 대칭키 암호화 방식보다 속도가 현저히 느리다는 단점이 있다.
HTTPS 원리
HTTPS는 위의 대칭키 암호화 방식과 공개키 암호화 방식을 모두 활용한다.
실제로 어떻게 통신이 이뤄지는지 같이 밑의 과정을 살펴보자.

[STEP 1]
먼저 클라이언트는 서버에게 사용가능한 암호화/해시 알고리즘과 random 값을 전달한다.
이때 random 값은 추후 대칭키를 만드는 과정에서 사용된다.
[STEP 2]
서버는 전달받은 암호화/해시 방식 중 우선순위가 높은 옵션을 선택해서 클라이언트에게 random 값과 함께 전달한다.
이렇게 되면 클라이언트와 서버 모두 2개의 random 값을 보유하게 된다.
[STEP 3]
서버는 자신의 응답을 증명하기 위해서 인증기관(CA)로 부터 디지털 서명을 받아서 클라이언트에게 전달한다.
[STEP 4]
클라이언트는 공개된 Root CA의 퍼블릭 키를 통해서 디지털 서명을 복호화하여 해당 인증서를 검증한다.
검증이 끝났으면 클라이언트는 해당 인증서에 적힌 public 키를 믿고 사용할 수 있다.
[STEP 5]
서버는 자신이 보낼 정보를 모두 보냈음을 알린다.
[STEP 6]
클라이언트는 암호화에 사용할 키를 만들기 위한 재료인 Pre Master Secret을 생성한다.
클라이언트는 임의로 만든 해당 키를 서버의 public키로 암호화하여 서버에 전달한다.
[STEP 7]
서버는 자신의 Private키를 이용해 Pre Master Secret을 추출한다.
[STEP 8]
서버와 클라이언트는 이전에 주고받았던 random 값과 Pre Master Secret을 통해 Master Secret을 생성한다.
그리고 이를 통해 Session 키와 MAC 키를 생성한다.
이때 Session 키는 암호화 및 복호화를 할 수 있는 대칭키이고, MAC 키는 데이터의 변조 여부를 확인할 수 있다.
이후 클라이언트와 서버는 MAC 값과 데이터를 Session 키로 암호화하여 데이터를 주고 받을 수 있다.
로컬 환경 HTTPS 적용시키기
개발자는 역시 실습을 해봐야된다 로컬 환경에서 HTTPS를 적용시켜보자!
실습 환경은 다음과 같다.
OS: Sonoma 14.2.1
Framework: Spring Boot 3.2.3
JDK Version: 17
Build: Apache Maven 3.9.6


먼저 다음과 같이 간단한 프로젝트를 생성한다.

keytool -genkeypair -alias mykey -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore keystore.p12 -validity 3650
그리고 프로젝트 폴더 내에서 다음과 같이 명령어로 정보를 입력하여 CA 인증서와 개인 키를 생성한다.
이때 입력했던 비밀번호는 꼭 기억해야 한다.

정상적으로 생성이 완료됐다면, 다음과 같이 keystore.p12 파일이 생성되었을 것이다.

그리고 application.yml 설정 파일에 정보를 입력해준다.

이제 서버를 구동하고 https로 접속을 시도해보면 다음과 같이 창이 뜰 것이다.
다음과 같이 주의 요함이 발생하는 이유는, 일반적으로 keytool을 사용하여 생성된 자체 서명된 SSL 인증서는 클라이언트에 의해 신뢰되지 않기 때문에 발생한다. 따라서, 클라이언트가 신뢰할 수 있는 인증 기관에서 발급된 인증서를 이용해야만 경고 페이지가 뜨지 않는다.

그래도 꾸역꾸역 비집고 들어가보면 다음과 같이 https로 접속이 되었다는 것을 확인할 수 있다.
만약 이미 도메인 주소를 구입한 상태이고 HTTPS를 적용시키고 싶다면 아래 포스팅 글을 읽어보자. 정리가 아주 잘 되어있다 👍
SSL 보안 인증서 무료 발급 받기 [SSL For Free]
Get SSL Security Certificate Free [SSL For Free] SSL [Secure Socket Layer] 서버와 사용자(브라우저) 간의 통신을 할 경우 정보를 함호화 하고 도중에 해킹을 통해 정보가 유출이 된다고 하더라도 정보의 내용을
foxydog.tistory.com
참고 문헌
HTTPS란? (동작방식, 장단점)
몇 년 전만 해도 전자 상거래 페이지가 있는 웹사이트에서만 HTTPS를 사용하고 있었다. 그러나 2014년, 구글에서 HTTPS를 사용하는 웹사이트에 대해서 검색 순위 결과에 약간의 가산점을 주겠다고
rachel-kwak.github.io
HTTPS 원리 이해하기
https의 원리를 정확히 알고 계시나요? | 최근 대부분의 웹사이트는 HTTPS를 사용한다. 간단한 이벤트 페이지조차 예외가 아니다. 그만큼 보편적으로 사용되고 있는 것이 바로 HTTPS이다. 하지만 면
brunch.co.kr
로컬 Spring Boot에 SSL 적용하기
Facebook OAuth를 개발해야 하는 경우 등 로컬 환경에서 HTTPS 서버가 필요할때가 종종 있습니다. (페이스북 OAuth 설정 화면) 운영 혹은 개발 환경에서는 Nginx 혹은 AWS ELB와 같은 곳에서 SSL 인증서를 설
jojoldu.tistory.com