서버 개발자로 일하면서 매일 쓰는 HTTP를 한번 정리하면 좋을듯 하다.
HTTP는 하이퍼 텍스트 전송 프로토콜로 처음에는 World Wide Web도입을 추진하기 위해 브로우저에서 간단한 키워드나 문서 경로 조회로 시작했지만 지금은 인터넷상에서 가장 많이 쓰이는 프로토콜로 자리잡았다.
지금 HTTP1.1과 다르게 프로토콜은 매우 간략했다.
현재 가장 많이 쓰이는 HTTP1.1과는 다르게 클라이언트 요청은 하나의 ASCII캐릭터 문자열 이였으며
서버의 응답은 HTML이였다. 커넥션은 문서 전송이 모두 완료되면 종료되었다.
헤더나 다른 메타데이터는 존재하지 않았다.
HTTP/0.9에서의 많은 불편함을 개선하기위해서 메타데이터 제공, 콘텐츠 협상 기능, 응답 상태값 등이 추가되었다. 이때부터 HTML로 한정되어있던 응답 데이터가 다양해젔다.
0.9때와 마찬가지로 커넥션은 요청이 끝나면 바로 종료시켰다.
0.9, 1.0은 써본적이 없는거 같다.
현재 우리가 가장 많이 사용하는 있는 버전이 아닌가 싶다.
1.1로 넘어오면서 블록 단위 인코딩 전송, 바이트 범위 요청, 캐시 메커니즘, 전송 인코딩, 쿠키 등 다양한 기능이 요청마다 협상할 수 있도록 추가되었고 Keep-alive가 기본으로 사용하도록 변경되었다. 클라이언트가 Connection: close를 요청받지 않는 한 서버는 기본적으로 커넥션을 열어 둔다.
HTTP/1.1의 성능의 한계를 해결하기 위해 만들어 젔다.
가장 큰 차이점은 요청 응답 멀티플렉싱, HOL해결, 우선순위 등이 있지만 핵심은 TCP프로토콜을 더 효율적으로 사용하는 방향으로 바뀐듯 하다.
따로 글을 정리하는게 나을듯 하다.
따로 글을 정리하는게 좋을듯 싶지만 아직 공부가 더 필요하다..
GET /index.html HTTP/1.1 # Start Line
# Header
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Connection: keep-alive
HTTP Version, URI, Method가 나온다.
Request Header는 통신하는데 필요한 모든 부가 정보가 담긴다.
예를들어 선호하는 언어(Accept-Language), 선호하는 인코딩 방식(Accept-Encoding), User-Agent 등이 있다.
위 예제는 GET요청이기 때문에 본문이 없지만 만약 POST, PUT, PATCH요청을 보낸다면 관련되 내용은 Body에 담아 보내야 한다.
HTTP/1.1 200 OK
Date: Fri, 22 Oct 2023 12:34:56 GMT
Server: Apache/2.4.28 (Unix)
Content-Length: 1234
Content-Type: text/html
<html>
<head>
<title>jibeagagoshipdda</title>
</head>
<body>
<h1>hello world</h1>
<p>remove the 'o'</p>
</body>
</html>
HTTP Version, Status Code, Status Message가 나온다.
Response의 Header는 조금 중요하다.
Request와 마찬가지로 Body의 컨텐츠의 관련된 내용들도 있으며 캐시 관련된 내용들도 같이 존재한다.
Etag, Expire등 Body의 리소스들의 캐시관련된 내용도 있으니 자세히 확인해봐야한다.
요청한 리소스에 대한 정보들이 담겨 있다.
그렇다면 https는 무엇일까?
https는 HTTP 프로토콜 상위에서 TLS 암호화를 구현한 형태이다.
그러면 TLS가 무엇이고 사람들이 헷갈리는 TLS, SSL에 대해서 정리를 해보자.
TLS에 대해서 정리는 따로 글을 작성하는게 나을듯 싶어 간단하게만 정리해보겠다.
TLS는 어느 계층에 있을까...?
사실 잘 모르겠다. 예전에 면접에서도 어느계층이냐고 물어봤는데 전송계층하고 어플리케이션계층 중간인데 잘 모르겠다고 대답했다...
글을 쓰고있는 지금도 잘 모르고있다. 나는 정말 대단하다.
TLS and SSL do not fit neatly into any single layer of the OSI model or the TCP/IP model.
-https://en.wikipedia.org/wiki/Transport_Layer_Security-
다행이다. (session쪽에 가장 유력해 보이긴 한다...)
SSL 프로토콜은 전자상거래 보안을 강화를 위해 처음 개발되었다고 한다.
안전한 전자상거래를 위해서는 개인정보 암호화, 인증처리, 데이터 무결성 등 여러 보안 기제가 필요한데, SSL 프로토콜은 TCP의 바로 위에서 작동함으로써 위 계층의 프로토콜이 별다른 수정 없이 안전하게 데이터를 주고받을 수 있게 되었다.
SSL3.0이 나오고 조금 더 업그레이드 되며 TLS1.0가 되었다.
두 프로토콜의 차이는 크지 않지만 상호 운용이 가능할정도는 아니며 IETF가 SSL프로토콜을 표준화한 후 SSL명칭이 TLS로 변경되었다. 어쨋든 두 명칭은 기술적으로 다른 버전의 프로토콜을 지칭하고 있으니 구분해서 부르는것이 맞다.
TLS 프로토콜은 위 계층에서 실행되는 모든 애플리케이션에게 암호화, 인증, 데이터 무결성이라는 세 가지 기능을 제공한다.
암호화된 안전한 데이터 채널을 구축하려면, 먼저 커넥션 피어들이 암호화 방식과 데이터를 암호화하는 데 사용할 키를 정해야 한다.
TLS 프로토콜은 이 과정에서 잘 정의된 핸드셰이크 시퀀스를 수행하는데 특별한 점은 공개키와 대칭키를 모두 사용한다.
클라이언트와 서버가 TLS를 통해 데이터를 주고받기 전에 먼저 암호화된 터널을 형성해야 한다.
먼저 TLS프로토콜 버전과 암호 방식을 합의하고 필요한 경우 인증서를 확인한다.
TLS핸드쉐이크의 내용을 간략하게 정리해봤다. TLS버전에 올라감에 따라 과정이 간소화되거나 변경되는 부분들이 있을것으로 확인되나 대략정인 순서는 위와 같다고 생각하면 될듯 하다.
공개키 암호화는 TLS터널을 초기화할 때만 사용한다. 서버가 클라이언트에게 공개키를 제공하면 클라이언트는 그것을 사용하여 대칭키를 생성하고, 암호화된 대칭키를 서버에게 전달한다.
그 후 서버는 자신의 개인키를 이용하여 클라이언트에게 받은 대칭키를 복화화 할 수 있다.
대칭키는 클라이언트와 서버 사이에서 발생하는 모든 커뮤니케이션에 사용된다.
대칭키가 사용되는 가장 큰 이유는 성능이다. 공개키 암호화를 사용하면 연산처리 비용이 크기 때문이다.