[네트워크] HTTP / HTTPS

정한별·2024년 2월 4일

네트워크

목록 보기
1/13

(항상 잘못된 정보가 포함되어 있을수 있습니다)
(잘못된 정보가 있다면 댓글로 피드백 부탁드리겠습니다)

HTTP

HTTP는 HyperText Transfer Protocol 약자로
클라이언트와 서버간의 정보를 주고 받기 위한 일종의 규약, 규칙을 나타낸다.
이름과 다르게 하이퍼 텍스트만 주고 받진 않는다.
이러한 규약, 규칙을 만들어두었기 때문에 많은 프로그램들이 이 규칙에 맞춰 개발해서
서로 정보를 주고 받을수 있게 된것이다.

하이퍼 텍스트: 플레인 텍스트와 달리 문장이나 단어 등이 하이퍼 링크를 통해 서로 연결된 네트워크처럼 구성된 문서를 말한다.
플레인 텍스트 = 선형 텍스트 = 책같이 아래로 내려가면서 읽는
하이퍼 텍스트 = 비선형 텍스트 = 중간중간 다른 텍스트를 볼수 있는

예시를 한번보자.

http://www.naver.com

www.naver.com 라는 인터넷 주소가 가진 데이터의 대한 정보를 주고 받는 행위를 우리는 HTTP 규칙대로 할꺼야 라는 의미를 담고 있다.

요청(request)과 응답(response)

HTTP는 요청(request)과 응답(response)의 구조를 가지고 있으며
HTML, Text, Image, 음성, 파일, JSON, XML
거의 모든 형태의 데이터를 주고 받는것이 가능

클라이언트는 HTTP 규칙에 맞게 메시지를 만들어서 서버에 요청하고 응답이 올때까지 기다린다.
이러한 요청들은 서로 독립적으로 작동한다. 하나의 요청과 다른 하나의 요청은 연관성이 없다.

서버는 요청이 온것을 확인하고 이에 맞는 응답을 준다.
서버는 클라이언트의 상태를 기억하지 않는다. 이전에 수행된 요청에 대한 정보를 저장한다거나 유지하지 않는다.
각각의 요청들은 모두 필요한 정보를 재각각 가지고 있어야 한다.

응답 역시 이전에온 한개의 인증과 이후에 온 인증과의 연관성이 없다.

이러한 특징들을 가지고 HTTP를
상태를 가지고 있지 않는 "Stateless 프로토콜" 이라고 부른다.

HTTP 메시지

HTTP 메시지는 서버와 클라이언트 간에 데이터가 교환되는 방식이다.
메시지 타입은 두가지가 있다.
클라이언트가 서버로 전달해서 액션이 일어나게끔 하는 메시지인 요청과
요청에 대한 서버의 답변의 내용을 담고 있는 응답 두가지 타입이 있다.

HTTP 요청 메시지

요청메시지는 서버가 특정 동작을 취하게끔 만들기 위해 클라이언트에서 전송하는 메시지 이다.

출처 https://developer.mozilla.org/ko/docs/Web/HTTP/Messages

시작 줄

POST /path/to/resource HTTP/1.1

시작줄은 다음과 같이 세가지 요소로 이루어 진다.

  • HTTP 메서드
    영어 동사(GET, PUT, POST) 혹은 명사 (HEAD, OPTIONS) 등을 사용해 서버가 수행해야할 동작을 나타낸다.
    예를들어 GET은 리소스를 클라이언트로 가져다 달라는 것을 뜻하며, POST는 데이터가 서버로 들어가야 함을 의미한다.

    메서드 목록 https://developer.mozilla.org/ko/docs/Web/HTTP/Methods

  • 요청 경로
    URI라고 하며, 실제 요청하려는 리소스가 담긴 경로를 표기한다.

URI - Uniform Resource Identifier
네트워크상에서 어떤 자원을 식별하기 위한 문자열의 구성

예시
/user/userinfo/get_userData.htm?=signup_year=2023

  • HTTP 버전
    응답 메시지에서 써야 할 HTTP 버전을 알려주는 역할을 한다.

요청 헤더

클라이언트와 부가적인 정보를 전송할 수 있도록 해준다.
이러한 부가적인 정보를 "메타 정보" 라고도 부른다.
HTTP 헤더는 대소문자를 구분하지 않는 이름과 콜론 ':' 다음에 오는 값(줄 바꿈 없이)으로 이루어져 있다.
또한 필요한 만큼 여러줄로 작성할 수 있다.

ex)
Host: localHost:8000
Content-type: application/json

본문

본문은 요청의 마지막 부분에 들어간다.
클라이언트가 서버로 전송하는 데이터를 포함하는 부분이다.
모든 요청에 본문이 들어가지는 않는다.
GET, HEAD, DELETE , OPTIONS처럼 리소스를 가져오는 요청은 보통 본문이 필요가 없다.

이렇게 본문이 필요가 없는경우 보통 본문이 없는 대신 시작줄에 요청경로에 그 정보를 담아 보낸다.

넓게 보면 본문은 두가지로 나뉜다.

  • 단일 파일로 구성되는 단일-리소스 본문(single-resource bodies)
  • 각각 서로 다른 정보를 담고 있는 멀티파트 본문으로 구성되는 다중 리소스 본문 (multipart/form-data)

HTTP 응답 메시지

출처 https://developer.mozilla.org/ko/docs/Web/HTTP/Messages

상태 줄

HTTP/1.1 200 OK

HTTP 응답의 시작 줄은 '상태 줄(status line)'' 이라고 불리며, 다음과 같은 정보를 가지고 있다.

  • 프로토콜 버전(HTTP version)
    HTTP/1.1
  • 상태 코드(Status Code)
    공, 실패 등의 상태를 나타내는 세 자리 숫자이다.
    200, 404 등등..

    https://developer.mozilla.org/ko/docs/Web/HTTP/Status/100
    응답코드 목록

  • 상태 메시지(Status Message)
    사람이 HTTP 메시지를 이해할 때 도움이 되는 상태 코드에 대한 짧고, 순전히 정보 제공 목적의 '상태 텍스트'
    OK 또는 Not Found 등등..

응답 헤더

응답 헤더는 요청헤더와 기본적으로 같은 구조를 가지고 있다.

본문

본문은 응답의 마지막 부분에 들어간다.
서버가 클라이언트에게 전송하는 데이터를 포함하는 부분이다.
이는 클라이언트가 요청한 리소스, 정보, 또는 상태를 포함할 수 있다.
모든 응답에 본문이 들어가지는 않는다.
해당 페이로드 없이도 요청에 충분히 응답하는 201, 204과 같은 상태 코드를 가진 응답에는 보통 본문이 없다.

넓게 보면 본문은 세가지 종류로 나뉜다.

  • 단일 파일로 구성되는 단일-리소스 본문(single-resource bodies)
  • 청크로 나뉘어 인코딩된 길이를 모르는 단일 리소스 본문
  • 각각 서로 다른 정보를 담고 있는 멀티파트 본문으로 구성되는 다중 리소스 본문 (multipart/form-data)

HTTPS

방금까지 배운 HTTP는 암호화가 되지 않은 평문 데이터를 주고 받는 프로토콜이였기에
누군가네트워크에서 데이터를 가로채는 공격에 취약 했다.
HTTP로 주민번호나 비밀번호등을 주고 받으면 이 정보를 제3자가 볼수 있다는 소리다.
이러한 문제를 해결 하기 위해서 나온게 HTTPS 다.
맨뒤에 있는 S가 바로 Secure 다.
HTTP에 데이터 암호화가 추가된 프로토콜이다.
HTTPS는 HTTP(80번)와 다르게 443번 포트를 사용하며,
네트워크 상에서 중간에 제3자가 정보를 볼 수 없도록 암호화를 지원하고 있다.

이전에 쓴 Hash 포스팅

https://velog.io/@ekdj98/What-Hash-1-%ED%95%B4%EC%8B%9C-%ED%95%A8%EC%88%98

에서 배운것중 하나가 바로 암/복호화였는데 거기서
이미 우리는 대칭키가 뭔지 비대칭키가 무엇인지 정도는 알았다.
여기서 조금 딥하게 알아보자

대칭키

장점으로는 속도와 효율성이 높다는 점이다.
대칭키 암호화는 비대칭키 암호화의 비해 데이터를 빠르게 암호화하고 복호화할 수 있다.
이는 성능 면에서 효율적이며 높은 처리 속도를 제공한다.

단점으로는 Key를 배포 및 공유하고 관리함에 있어서 보안적인 문제가 크다.
Key를 클라이언트가 가지고 있자니 클라이언트가 털러버리면 끝이다.
예를들어 앱 내에 Key를 가지고 있다가 누가 앱을 까서 보면 Key가 털려버린다.

그럼 서버에서 클라로 Key를 주는건 어때?
중간에서 이 Key를 봐버리면 또 Key가 털려버린다.
이와 같이 키를 공유하고 관리함에 있어서 굉장히 위험한게 대칭키다.

비대칭키

장점으로는 안전한 Key 교환이 가능하다는 점이다.
공개키개인키 2개가 있어야 하기 때문에 보안적으로 우수하다.
클라이언트가 공개키를 가지고, 서버가 개인키를가지고 데이터를 암호화 하면
클라이언트를 털어서 공개키를 알아내더라도 데이터를 알아 낼 방법이 없다.
내가 개인키를 알지못하면 결국 복호화를 할수 없으니.

하지만 단점도 있다.
계산 복잡성으로 인해 대칭키 암호화에 비해 더 많은 계산 리소스가 필요하며,
이는 대용량 데이터 전송에 있어서 속도가 느리고 비용이 증가하는 요인이 될 수 있다.

HTTPS에서의 암호화

HTTPS에서는 이러한 대칭키 암호화 방식과 비대칭키 암호화 방식을 모두 사용해서
대칭키 방식의 빠른연산속도라는 장점과 비대칭키 방식의 보안 안전성에 대한 장점만을 뽑아서 사용중이다.

비대칭키 방식을 이용해서 대칭키 암호화 방식에 사용할 키인 "세션키"보안적으로 아주 안전하게 교환하고
"세션키"를 기반으로 대칭키 암호화 방식을 이용해서 많은 데이터를 아주 빠르게 교환한다.

HTTPS에서 비대칭키 방식으로 암호화한 키를 "세션키" 라고 부른다.
이 "세션키"를 주고받을 데이터를 대칭키 방식의 암호화를 할때 쓴다.

또한 실제 HTTPS의 이러한 암호화 작업 및 흐름을
TLS 암호화, TLS Handshake 라고 부른다

TLS Handshake

Client Hello

클라이언트가 서버로 메시지 전송
이 메시지엔 클라이언트가 지원하는 암호화 방식과 난수 한개를 같이 보낸다
이 난수는 나중에 대칭키를 만들때 사용한다
(Session ID를 함께 전송 이건 일단 맨 하단에서 다룰 예정)

Server Hello

클라이언트가 보낸 메시지에 대한 응답 메시지
클라이언트가 지원하는 암호화방식중 서버가 가능한 방식을 선택하고 역시나 난수 한개를 같이 보낸다.
이 난수 역시 나중에 대칭키를 만들때 사용한다
(Session ID를 함께 전송 이건 일단 맨 하단에서 다룰 예정)

Certificate

서버가 클라이언트에게 전송하는 인증서

이 인증서엔 서버가 비대칭키 암호화에서 사용하는 키중 하나인 공개키도 같이 전송한
다. (복호화 할때 사용하는 개인키는 서버가 따로 보관)

클라이언트는 이 인증서를 받고 이 인증서가 무결한지 검증한다.

Server Hello Done

서버가 클라이언트에게 보낼 메시지를 모두 보냄

Client Key Exchange

클라이언트가 생성한 난수 + 서버가 보내온 난수
에 인증서에 담겨있던 공개키를 사용해 비대칭키 암호화
이것이 바로 추후 데이터를 대칭키 암호화 할때 쓰는
세션키 다.

이렇게 암호화 한 값을 다시 서버로 전송

그럼 서버는 암호화 된값을 서버가 가지고있는 개인키를 이용해 복호화 해서
세션키를 습득
이렇게 서버와 클라이언트 모두 안전하게 세션키를 가질수 있게 됨

Finished

이제 서로 주고받는 데이터를 세션키를 가지고 암호화 복호화 하며
데이터를 주고 받을수 있게 됨

Session ID

그렇다면 통신할때마다 이 과정을 반복하는가? 그건 아니다.
매번 연결할 때마다 Handshake 과정을 진행하는 것은 비효율적이니 최초 한번 전체
클라이언트는 최초에 Handshake 과정을 진행할때 Session ID를 빈값을 보낸다.
그럼 서버는 Session ID를 하나 주게된다.
그리고 이 과정을 정상적으로 마치고 난뒤에는
이 검증된 Session ID를 사용해서 위 과정을 반복해서 진행하지 않고 통신한다.
클라이언트가 이 Session ID를 가지고 있다가 통신을 할일이 생기면 이 Session ID를 서버로 전송하고
서버는 이 ID가 아직 유효하다면 Handshake 과정을 반복하지 않고 통신을 수행한다.

profile
iOS Developer

0개의 댓글