[HTTP 완벽 가이드] - 보안HTTP, 엔터티와 인코딩

Lee Jeong Min·2022년 4월 25일
0

네트워크

목록 보기
16/17
post-thumbnail

14장 보안 HTTP

HTTP를 안전하게 만들기

인터넷 뱅킹과 같은 중요한 일을 웹에서도 할 수 있게 웹은 안전한 방식의 HTTP를 필요로 한다.

이와 같은 중요한 트랜잭션을 위해, HTTP와 디지털 암호화 기술을 결합해야한다.

아래와 같은 조건들을 제공해주어야 함.

  • 서버 인증 - 클라이언트는 자신이 위조된 서버가 아닌 진짜와 이야기하고 있음을 알 수 있어야 한다.
  • 클라이언트 인증 - 서버는 자신이 가짜가 아닌 진짜 사용자와 이야기하고 있음을 알 수 있어야 한다.
  • 무결성 - 클라이언트와 서버는 그들의 데이터가 위조되는 것으로부터 안전해야 한다.
  • 암호화 - 클라이언트와 서버는 도청에 대한 걱정 없이 서로 대화할 수 있어야 한다.
  • 효율 - 저렴한 클라이언트나 서버도 이용할 수 있도록 알고리즘은 충분히 빨라야 한다.
  • 편재성(Ubiquity) - 프로토콜은 거의 모든 클라이언트와 서버에서 지원되어야 한다.
  • 관리상 확장성 - 누구든 어디서든 즉각적인 보안 통신을 할 수 있어야 한다.
  • 적응성 - 현재 알려진 최선의 보안 방법을 지원해야 한다.
  • 사회적 생존성 - 사회의 문화적, 정치적 요구를 만족시켜야 한다.

HTTPS

HTTPS는 HTTP를 안전하게 만드는 방식 중에서 가장 인기 있는 것이다. 이를 사용하면, 모든 HTTP 요청과 응답 데이터는 네트워크로 보내지기 전에 암호화 된다.

여기서의 보안 계층은 안전 소켓 계층(SSL) 혹은 이를 계승한 전송 계층 보안(TLS)을 이용하여 구현된다.

디지털 암호학

HTTPS에 대해 자세히 이야기 하기 전, SSL과 HTTPS에서 이용되는 암호 인코딩 기법에 대한 약간의 배경지식을 알아보자.

기술과 용어

  • 암호: 텍스트를 아무나 읽지 못하도록 인코딩 하는 알고리즘
  • 키: 암호의 동작을 변경하는 숫자로 된 매개변수
  • 대칭키 암호 체계: 인코딩과 디코딩에 같은 키를 사용하는 알고리즘
  • 비대칭키 암호 체계: 인코딩과 디코딩에 다른 키를 사용하는 알고리즘
  • 공개키 암호법: 비밀 메시지를 전달하는 수백만 대의 컴퓨터를 쉽게 만들 수 있는 시스템
  • 디지털 서명: 메시지가 위조 혹은 변조되지 않았음을 입증하는 체크섬
  • 디지털 인증서: 신뢰할 만한 조직에 의해 서명되고 검증된 신원 확인 정보

비밀 코드의 기술과 과학

암호법은 메시지 인코딩과 디코딩에 대한 과학이자 기술이다.

암호(cipher)

암호법은 암호라 불리는 비밀 코드에 기반한다.

암호란 메시지를 인코딩 하는 어떤 특정한 방법과 나중에 그 비밀 메시지를 디코딩하는 방법이다.

책의 그림 14-3 참고

암호 기계

암호는 처음에 간단한 알고리즘으로 시작했지만, 기술이 진보하면서 보다 복잡한 암호로 메시지를 빠르고 정확하게 인코딩하고 디코딩하는 기계를 만들기 시작했다.

키가 있는 암호

코드 알고리즘과 기계가 적에 손에 들어가도, 대부분의 기계들에는 암호의 동작방식을 변경할 수 있는 큰 숫자로 된 다른 값을 설정할 수 있는 다이얼이 달려있다.
➡️ 이러한 암호 매개변수를 키라고 부른다.

키에따라 디코딩이 제각각으로 동작한다.
오늘날의 거의 대부분의 암호 알고리즘은 키를 사용한다.

디지털 암호

두 가지 주요한 발전

  • 속도 및 기능에 대한 기계 장치의 한계에서 벗어남으로써, 복잡한 인코딩과 디코딩 알고리즘이 가능해졌다.
  • 매우 큰 키를 지원하는 것이 가능해져서, 단일 암호 알고리즘으로 키의 값마다 다른 수조 개의 가상 암호 알고리즘을 만들어낼 수 있게 되었다. 키가 길수록 인코딩의 많은 조합이 가능해지고 무작위로 추측한 키에 의한 크래킹이 어려워진다.

대칭키 암호법

대칭키 암호법은 인코딩할 때 사용하는 키가 디코딩 할 때와 같은 것을 의미한다.
➡️ 아래 그림에선 (e = d)

인코더              --------------       디코더

C = E(P,e)                          P = D(C,d)

P: 평문                              P: 평문
e: 키                               d: 키
E: 인코더                            D: 디코더
C: 암호문                            C: 암호문

키 길이와 열거 공격

평범한 대칭키 암호는 오늘날의 슈퍼 컴퓨터로 간단하게 뚫릴 수 있다.

그래서 키를 사용할 때, 비트수가 높은 것을 사용하는 것이 암호를 지키는데 안전하다.

공유키 발급하기

대칭키 암호화의 단점 중 하나는 발송자와 수신자가 서로 대화하려면 둘 다 공유키를 가져야 한다는 것이다.

만약 N개의 노드가 있고, 각 노드가 N-1 상대와 은밀하게 대화를 나누어야 한다면, 대략 총 N^2개의 비밀 키가 필요하다.

공개키 암호법

한 쌍의 호스트가 하나의 인코딩/디코딩 키를 사용하는 대신 공개키 암호 방식은 두 개의 비대칭 키를 사용한다.

인코딩 키: 모두에게 공개되어 있는 공개키
디코딩 키: 호스트만이 갖고 있는 개인키

이렇게 하면 대칭 키의 쌍이 N^2으로 증가하는 것을 피할 수 있다.

RSA

공개키 비대칭 암호의 과제는 아래의 내용을 알고 있더라도 비밀인 개인 키를 계산할 수 없다는 것을 확신시켜주는 것이다.

  • 공개키(물론 공개니까 누구나 얻을 수 있다)
  • 가로채서 얻은 암호문의 일부(네트워크를 스누핑해서 획득)
  • 메시지와 그것을 암호화한 암호문(인코더에 임의의 텍스트를 넣고 실행해서 획득)

➡️ 이 모든 요구를 만족하는 공개키 암호 체계중 유명한 하나는 MIT에서 개발한 RSA 알고리즘

혼성 암호 체계와 세션 키

공개키 암화 방식의 알고리즘은 계산이 느린 경향이 있다.

따라서 노드간 연결이 맺어지고 나서 이후의 나머지 데이터를 암호화할 때는 빠른 대칭 키를 사용하는 방식이 흔히 쓰인다.

디지털 서명

암호 체계는 누가 메시지를 썼는지 알려주고 그 메시지가 위조되지 않았음을 증명하기 위해 메시지에 서명을 하도록 하는 데에 이용될 수 있다.

서명은 암호 체크섬이다

디지털 서명은 메시지에 붙어있는 특별한 암호 체크섬으로, 메시지를 작성한 저자가 누구인지 알려주고 메시지 위조를 방지한다.

저자의 개인 키는 일종의 '지문'처럼 사용된다.

디지털 인증서

디지털 인증서는 인터넷의 신분증이며 신뢰할 수 있는 기관으로부터 보증 받은 사용자나 회사에 대한 정보를 담고 있다.

인증서의 내부

디지털 인증서에는 공식적으로 '인증 기관'에 의해 디지털 서명된 정보의 집합이 담겨있다.

인증서 안에 존재하는 것들

  • 대상의 이름(사람, 서버, 조직 등)
  • 유효 기간
  • 인증서 발급자(누가 이 인증서를 보증하는가)
  • 인증서 발급자의 디지털 서명

X.509 v3 인증서

디지털 인증서에 대한 전 세계적인 단일 표준은 없지만, 오늘날 사용되는 대부분의 인증서가 그들의 정보를 X.509라고 불리는 표준화된 서식에 저장하고 있다.

서버 인증을 위해 인증서 사용하기

사용자가 HTTPS를 통한 안전한 웹 트랜잭션을 시작할 때, 최신 브라우저는 자동으로 접속한 서버에서 디지털 인증서를 가져온다. 이후 이것을 검사한다.

HTTPS의 세부사항

HTTPS는 HTTP 프로토콜에 대칭, 비대칭 인증서 기반 암호 기법의 강력한 집합을 결합하여 분권화된 글로벌 환경에서도 HTTPS를 매우 안전한 동시에 매우 유연하고 관리하기 쉽게 만들어 준다.

HTTPS 개요

HTTPS는 HTTP 메시지를 TCP로 보내기 전에 먼저 그것들을 암호화하는 보안 계층으로 보낸다.

오늘날 HTTPS 보안 계층은, SSL과 그것의 현대적 대체품인 TLS로 구현되었다.

HTTPS 스킴

https로 시작하는 스킴 접두사를 가진다.

또한 클라이언트는 서버에 443번 포트로 연결하고 서버와 바이너리 포매승로 된 몇몇 SSL 보안 매개변수를 교환하면서 '핸드셰이크'를 하고, 암호화된 HTTP 명령이 뒤를 잇는다

보안 전송 셋업

HTTPS에서의 절차는 TCP 연결이후, 클라이언트와 서버간 암호법 매개변수와 교환 키를 협상하면서 SSL 계층을 초기화한다.

핸드셰이크 완료 후 SSL 초기화가 완료되며, 클라이언트는 요청 메시지를 보안 계층에 보내는데, 이 메시지는 암호화되어 보내진다.

SSL 핸드셰이크

핸드셰이크에서는 다음과 같은 일이 일어난다.

  • 프로토콜 버전 번호 교환
  • 양쪽이 알고 있는 암호 선택
  • 양쪽의 신원 인증
  • 채널을 암호화하기 위한 임시 세션 키 생성

서버 인증서

서버 인증서는 조직의 이름, 주소, 서버 DNS 도메인 이름, 그외 정보를 보여주는 X.509 v3에서 파생된 인증서 이다.

사이트 인증서 검사

웹 서버 인증서 검사를 위한 알고리즘의 단계는 아래와 같다.

  1. 날짜 검사
    인증서가 유효한지 확인하기위해 시작 및 종료일을 검사

  2. 서명자 신뢰도 검사
    어떤 인증 기관에의해 서명되었는지 확인한다.

  3. 서명 검사
    공개키를 서명에 적용하여 체크섬 검사한다.

  4. 사이트 신원 검사
    인증서의 도메인 이름과 서버의 도메인 이름과 비교하여 맞는지 검사한다.

가상 호스팅과 인증서

가상 호스팅(하나의 서버에 여러 호스트 명)로 운영되는 사이트는 인증서와 관련하여 다루기 까다로운 무넺가 있어서 보통 이를 피하기 위해 리다이렉트하는 방법을 사용한다.

프락시를 통한 보안 트래픽 터널링

프락시를 사용하는 경우, 클라이언트가 서버로 데이터를 보낼때 암호화하면 더 이상 HTTP 헤더를 읽을 수 없다.

이러한 경우 사용하는 것이 HTTPS SSL 터널링 프로토콜 이다. 이를 사용하면 클라이언트는 이 내용을 프락시가 읽을 수 있도록 암호화가 시작되기 전에 평문으로 말해준다.

15장 엔터티와 인코딩

HTTP는 다음을 보장한다.

  • 객체를 올바르게 식별(Content-Type 미디어 포맷 또는 Content-Langugage헤더를 이용)하여 브라우저나 다른 클라이언트가 콘텐츠를 바르게 처리할 수 있게함
  • 객체는 올바르게 압축이 풀림(Content-LengthContent-Encoding헤더)
  • 객체는 항상 최신(엔터티 검사기와 캐시 만료 제어)
  • 사용자의 요구 만족(내용 협상을 위한 Accept 헤더 기반)
  • 네트워크 사이를 빠르고 효율적으로 이동(범위 요청, 델타 인코딩, 그외 데이터압축)
  • 조작되지 않고 온전하게 도착(전송 인코딩 헤더와 Content-MD5 체크섬 이용)

이 모든 것을 가능하게 하기 위해 HTTP는 콘텐츠를 나르기 위한 잘 라벨링된 엔터티를 사용한다.

메시지는 컨테이너, 엔터티는 화물

HTTP 메시지를 인터넷 운송 시스템의 컨테이너라고 하면, HTTP 엔터티는 메시지의 실질적인 화물이다.

HTTP/1.1의 10가지 주요 엔터티 헤더 필드

  • Content-Type: 엔터티에 의해 전달된 객체의 종류
  • Content-Length: 전달되는 메시지의 길이나 크기
  • Content-Language: 전달되는 객체와 가장 잘 대응되는 자연어
  • Content-Encoding: 객체 데이터에 대해 행해진 변형(압축 등)
  • Content-Location: 요청 시점을 기준으로, 객체의 또 다른 위치
  • Content-Range: 부분 엔터티라면, 이 헤더는 이 엔터티가 전체에서 어느 부분에 해당하는지 정의
  • Content-MD5: 엔터티 본문의 콘텐츠에 대한 체크섬
  • Last-Modified: 서버에서 이 콘텐츠가 생성 혹은 수정된 날
  • Expires: 이 엔터티 데이터가 더 이상 신선하지 않은 것으로 간주되기 시작하는 날짜와 시각
  • Allow: 이 리소스에 대해 어떤 요청 메서드가 허용 되는지
  • ETag: 이 인스턴스에 대한 고유한 검사기
  • Cache-Control: 어떻게 이 문서가 캐시될 수 있는지에 대한 지시자

엔터티 본문

엔터티 본문은 가공되지 않은 데이터만을 담고 있다.

이 데이터의 의미에 대해 설명하는 엔터티 헤더로 Content-Type같은 엔터티가 있다.

Content-Length: 엔터티의 길이

이 헤더는 메시지의 엔터티 본문의 크기를 바이트 단위로 나타낸다.
➡️ 이 헤더는 서버 충돌로 인해 메시지가 잘렸는지 감지하고자 할 때와 지속 커넥션을 공유하는 메시지를 올바르게 분할하고자 할때 필요하다.

만약 인코딩이나 압축이 되었다면 압축된 후의 크기를 나타냄

잘림 검출

옛날 HTTP는 커넥션이 닫힌 것을 보고 메시지가 끝났음을 인지했는데, Content-Length가 없다면 클라이언트는 커넥션이 정상적으로 닫힌것인지, 전송 중 서버에 충돌이 발생한 것인지 구별 X

클라이언트는 메시지 잘림을 검출하기 위해 Content-Length를 필요로 한다.
특히 캐싱 프락시 서버에 취약하여 이 위험을 줄이기 위해 이 헤더를 갖고 있지 않은 HTTP 본문은 캐싱 X(잘렸다는 것을 인지하지 못해 캐시가 이를 저장하고 계속해서 제공하기에)

잘못된 Content-Length

Content-Length가 잘못된 값을 담고 있는 경우 아예 빠진 것보다도 큰 피해를 유발할 수 있다.

Content-Length와 지속 커넥션

Content-Length는 지속 커넥션을 위해 필수다.
➡️ Content-Length 헤더 없이 어디까지가 엔터티 본문이고 어디부터가 다음 메시지인지 알 수 없기 때문

이 헤더 없는 지속 커넥션을 만날 수 있는 상황은 청크 인코딩인 경우
청크 인코딩: 데이터를 각각이 특정한 크기를 갖는 일련의 청크들로 쪼개어 보내는것

콘텐츠 인코딩

HTTP는 보안을 강화하거나 압축을 통해 공간을 절약할 수 있도록 엔터티 본문을 인코딩할 수 있다.

엔터티 본문 길이 판별을 위한 규칙

이는 책 참고

엔터티 요약

HTTP가 일반적으로 TCP/IP와 같이 신뢰할 만한 전송 프로토콜 위에서 구현되지만, 여러가지 이유로 메시지의 일부분이 전송 중에 변형되는 일이 일어난다.

이러한 변경을 감지하기 위해 송신자는 데이터에 대한 체크섬을 생성할 수 있고 수신자는 그 체크섬으로 기본적인 검사를 할 수 있다.

Content-MD5 헤더는 서버가 엔터티 본문에 MD5 알고리즘을 적용한 결과를 보내기 위해 사용된다. ➡️ 메시지 무결성 검사를 위해 보통 쓰이며, 문서의 위치를 빠르게 알아내고 콘텐츠의 중복 저장을 방지하기 위한 해시 테이블의 키로 이용될 수 있다.

미디어 타입과 차셋(Charset)

Content-Type 헤더 필드는 엔터티 본문의 MIME 타입을 기술한다.

이 헤더는 원본 엔터티 본문의 미디어 타입을 명시한다. 즉 인코딩을 거친 경우에도 인코딩 전의 본문 유형을 명시한다는 의미

텍스트 매체를 위한 문자 인코딩

Content-Type 헤더는 내용 유형을 더 자세히 지정하기 위한 선택적인 매개변수도 지원한다.

Content-Type: text/html; charset=iso-8859-4

멀티파트 미디어 타입

MIME "멀티파트" 이메일 메시지는 서로 붙어있는 여러 개의 메시지를 포함하며 하나의 복합 메시지로 보내진다.

멀티파트 폼 제출

HTTP 폼을 채워서 제출하면, 가변 길이 텍스트 필드와 업로드 될 객체는 각각이 멀티파트 본문을 구성하는 하나의 파트가 되어 보내진다.

ex) html input에 text와 file을 같이 보내는 경우 멀티파트로 같이 보내짐

멀티파트 범위 응답

범위 요청에 대한 HTTP 응답 또한 멀티파트가 될 수 있다.

콘텐츠 인코딩

HTTP 애플리케이션은 때때로 콘텐츠를 보내기 전에 인코딩을 하려고 한다.

이를 통해 전송 시간을 줄이거나 암호화하는데 이점을 챙길 수 있다.

콘텐츠 인코딩 과정

  1. 웹 서버가 원본 Content-Type과 Content-Length 헤더를 수반한 원본 응답 메시지를 생성

  2. 콘텐츠 인코딩 서버가 인코딩된 메시지를 생성하고 Content-Encoding 헤더를 인코딩된 메시지에 추가하여 받는쪽에서 디코딩 가능하도록 함
    ➡️ Content-Length는 달라짐

  3. 수신 측 프로그램은 인코딩된 메시지를 받아서 디코딩하고 원본을 얻는다.

콘텐츠 인코딩 유형

HTTP는 몇 가지 표준 콘텐츠 인코딩 유형을 정의하고 확장 인코딩으로 인코딩을 추가하는 것도 허용한다.

인코딩 알고리즘에 고유한 토큰을 할당하는 IANA를 통해 표준화된다.

몇 가지 흔히 쓰이는 콘텐츠 인코딩 토큰

  • gizp
  • compress
  • deflate
  • identity

identity를 제외한 3개는 메시지의 크기를 정보의 손실 없이 줄이기 위한 무손실 압축 알고리즘이다.

Accept-Encoding 헤더

서버에서 클라이언트가 지원하지 않는 인코딩을 사용하는 것을 막기 위해, 클라이언트는 자신이 지원하는 인코딩 목록을 Accept-Encoding 요청 헤더를 통해 전달한다.

전송 인코딩과 청크 인코딩

전송 인코딩은 전체 메시지에 대해 적용되며, 구조적인 이유 때문에 적용된다.

안전한 전송

전송 인코딩은 다른 프로토콜에서도 네트워크를 통한 '안전한 전송'을 위해 존재했다.

알 수 없는 크기

콘텐츠 인코더는 콘테츠를 먼저 생성하지 않고서는 메시지 본문의 최종 크기를 판단할 수 없는데, 이 사이즈를 알기도 전에 데이터의 전송을 시작하려고 함

보안

전송 인코딩을 사용해 알아보기 어렵게 할 수 있지만 SSL과 같은 방식을 더 많이 씀

Transfer-Ecoding 헤더

전송 인코딩을 제어하고 서술하기 위해 정의된 헤더 2가지

  • Transfer-Encoding

    안전한 전송을 위해 어떤 인코딩이 메시지에 적용되었는지 수신자에게 알려줌

  • TE

    어떤 확장된 전송 인코딩을 사용할 수 있는지 서버에 알려주기 위해 요청 헤더에 사용

청크 인코딩

청크 인코딩은 메시지를 일정 크기의 청크 여럿으로 쪼갠다.

이는 전송 인코딩의 한 형태이며 따라서 본문이 아닌 메시지의 속성이다!

청크와 지속 커넥션

지속 커넥션에서는 Content-Length 헤더에 본문의 길이를 담아서 보내주어야 하는데, 동적으로 생성되는 경우에 알기 어렵다.
→ 이러한 딜레마를 청크 인코딩은 서버가 본문을 여러 청크로 쪼개 보낼 수 있게 해줌으로써 해결한다.

마지막에 서버는 크기가 0인 청크로 본문이 끝났음을 알린다.

청크 인코딩된 메시지의 트레일러

청크 메시지에 트레일러를 추가할 수 있는 경우

  • 클라이언트의 TE 헤더가 트레일러를 받아들일 수 있는 경우
  • 트레일러가 응답을 만든 서버에 의해 추가되었으며, 그 트레일러의 콘텐츠는 클라이언트가 이해하고 사용할 필요가 없는 선택적인 메타데이터이므로 클라이언트가 무시하고 버려도 되는 경우

전송 인코딩 규칙

전송 인코딩이 메시지 본문에 적용될 때, 몇 가지 규칙이 반드시 적용되어야 한다.

  • 전송 인코딩의 집합은 반드시 'chuncked'를 포함해야 한다.
  • 청크 전송 인코딩이 사용되었다면 메시지 본문에 적용된 마지막 전송 인코딩이 존재해야한다.
  • 청크 전송 인코딩은 반드시 메시지 본문에 한 번 이상 적용되어야 한다.

시간에 따라 바뀌는 인스턴스

HTTP 프로토콜은 어떤 특정한 종류의 요청이나 응답을 다루는 방법들을 정의하는데, 이를 인스턴스 조작이라 부른다.

대표적 두 가지

  • 범위 요청
  • 델타 인코딩

검사기와 신선도

이 부분은 7장-캐시에서 거의 다루었기 때문에 넘어감

범위 요청

클라이언트가 문서의 일부분이나 특정 범위만 요청할 수 있도록 해주는것

델타 인코딩

델타 인코딩은 객체 전체가 아닌 변경된 부분에 대해서만 통시한여 전송량을 최적화하는, HTTP 프로토콜의 확장이다.

서버에게 A-IM 이라는 받아들일 수 있는 인스턴스 조작의 종류를 가리키는 요청 헤더를 보내 델타 인코딩을 사용한다.

델타 인코딩은 필요한 부분만 보내 전송 시간을 줄일 수 있지만, 구현하기가 까다로울 수 있다. 또한 서버는 반드시 클라이언트가 가지고 있던 이전 버전의 사본들 모두를 유지해야 최신 사본간 차이점을 알아낼 수 있어서 디스크 공간을 더 소모한다.

profile
It is possible for ordinary people to choose to be extraordinary.

0개의 댓글