ShoppingMall Project

[Shop Project] HTTP vs HTTPS, SSL인증서 생성하기 (1)

sagecode 2025. 5. 28. 18:55

쇼핑몰 웹사이트를 개발하다 보면, 회원가입, 로그인, 결제 등 민감한 정보를 다루게 된다. 이 때 http://가 아닌 https://를 사용하는 것은 보안에 중요한 영향을 끼친다.


HTTP와 HTTPS의 차이를 공부한 다음 쇼핑몰 프로젝트에 HTTPS를 적용해보도록 하겠다.

 

HTTP란 무엇인가?

HTTP(HyperText Transfer Protocol)는 웹에서 클라이언트와 서버가 대화하는 방식을 정의한 규약이다. 브라우저가 서버에 요청(Request)을 보내고, 서버가 응답(Response)을 보내는 과정에서 사용된다.

 

처음에는 나도 '규약'이라는 단어가 너무 어색했다. 또한 실체가 없고 너무 추상적인 개념이라 조금 이해하기 어려웠다. 그래서 공부한 이후에 내가 이해한 방향으로 최대한 쉽게 설명해보도록 하겠다.

 

GET /login HTTP/1.1
Host: mysite.com
Authorization: ID:pass
User-Agent: Mozilla/5.0
  •  GET /login HTTP/1.1, mysite.com
    • GET(조회) 요청을 하였다.
    • mysite.com/login (경로)에 요청을 한 것이다. 하나의 IP에서 여러 도메인을 호스팅할 수 있기 때문에, 어떤 도메인에 대한 요청인지 명시해줘야 한다.
    • 현재 HTTP/1.1 버전을 사용중이다.
  • Authorization: ID:pass
    • 접속하려는 리소스에 접근 권한이 있는지 인증하기 위한 정보를 담고 있다.
    • 실제로는 Base64로 인코딩된 토큰이나 Bearer Token을 쓰는 경우가 대부분이다. (암호화 된 토큰)
  • User-Agent: Mozilla/5.0
    • 클라이언트(보통은 브라우저나 앱)가 자신이 어떤 환경에서 요청을 보냈는지 서버에 알려주는 정보이다.
    • 'Mozilla/5.0'는 웹 호환성(compatibility)을 위해 거의 모든 브라우저가 형식적으로 따라 쓰는 값이다.

HTTPS란 무엇인가?

HTTPS는 HTTP + TLS(또는 SSL) 입니다. HTTP 메시지를 그대로 사용하되, 그것을 암호화된 터널을 통해 전송하는 방식이다.

 

쇼핑몰 프로젝트에서는 이러한 데이터를 다룬다.

- 회원가입 시 입력한 이메일, 비밀번호
- 로그인 인증 정보
- 결제 정보 (카드번호, 주소 등)
- 쿠폰, 포인트 정보

이런 정보가 HTTP로 전송된다면, 네트워크 중간에서 서버인척하며 이를 가로채는 '인터셉터'의 위험이 있습니다. SSL/TLS 암호화를 통해 이 모든 정보를 안전하게 보호한다.

 

SSL/TLS는 보안 세션을 기반으로 데이터를 암호화하며 보안 세션이 만들어질 때 인증 메커니즘, 키 교환 암호화 알고리즘, 해싱 알고리즘이 사용된다. TLS는 암호화된 통로를 만들기 위해, 먼저 서버와 브라우저가 약속과 키 교환(TLS HandShake)을 한다.

 

보안세션

보안세션이란 보안이 시작되고 끝나는 동안 유지되는 세션을 말하고, SSL/TLS는 핸드셰이크를 통해 보안 세션을 생성하고 이를 기반으로 상태 정보 등을 공유한다.

  • 세션 : 운영체제가 어떠한 사용자로부터 자신의 자산 이용을 허락하는 일정한 기간을 뜻한다. 즉, 사용자는 일정 시간 동안 응용프로그램, 자원 등을 사용할 수 있다.

TLS handshake

1. Client Hello

브라우저가 서버에게 말 걸기 : 원하는 TLS 서버와 지원하는 암호화 방식을 서버에게 보낸다.

Client → Server
- 지원하는 암호 Suites 목록
- 랜덤 값 (Client Random)
- TLS 버전 정보 등

이렇게 TLS에서 사용하는 암호화 알고리즘들의 조합을 한 세트로 묶은 것을 'Cypher suites'라고 한다. 

프로토콜, AEAD 사이퍼 모드, 해싱 알고리즘이 나열된 규약을 말하며, 5개가 존재한다.

  • TLS_AES_128_GCM_SHA256
  • TLS_AES_256_GCM_SHA384
  • TLS_CHACHA20_POLY1305_SHA256
  • TLS_AES_128_CCM_SHA256
  • TLS_AES_256_CCM_8_SHA256

예를 들어 TLS_AES_128_GCM_SHA256은 TLS는 프로토콜, AES_128_GCM은 사이퍼 모드, SHA256은 해싱 알고리즘을 뜻한다.

 

2. Server Hello + 인증서 전송

서버가 답변함 : 암호화 방식 선택. 그리고 인증서와 공개키를 클라이언트에 전송한다.

Server → Client
- 선택된 암호화 방식
- 서버 인증서 (공개키 포함)
- 랜덤 값 (Server Random)

서버는 암호화 방식들중 그 중 하나를 골라 응답한다.

이 때, 서버가 클라이언트가 제안한 여러 Cipher Suite 중 어떤 걸 선택하느냐는 보안 수준, 성능, 설정 우선순위에 따라 달라질 수 있다.

 

1. TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
2. TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
3. TLS_RSA_WITH_AES_128_CBC_SHA
4. TLS_RSA_WITH_3DES_EDE_CBC_SHA

예를 들어, 위 같이 우선순위를 정해놓을 수 있다.

서버 종류 설정 위치 예시
Nginx ssl_ciphers, ssl_prefer_server_ciphers on;
Apache SSLCipherSuite, SSLHonorCipherOrder on
Java JVM의 SSLContext or springboot 설정
Node.js TLS 옵션의 ciphers 리스트

이런식으로 서버 종류에 따라 우선순위를 정하는 방식이 다르다.

 

그리고 자신의 신원을 증명할 수 있는 인증서(Certificate)를 같이 전송한다.

 

인증서란?

인증서는 서버가 진짜 신뢰할 수 있는 서버인지를 증명하는 디지털 문서다. 보통은 Let's Encrypt, DigiCert, GlobalSign 같은 공인된 인증기관(CA)에서 발급받는다.

 

인증서 안에는 다음 정보가 들어있다.

  • 서버의 도메인 이름
  • 공개키 (Public Key)
  • 발급자 정보 (CA)
  • 유효기간
  • 디지털 서명

클라이언트는 인증서를 아래와 같이 검증한다.

  1. 인증서가 신뢰할 수 있는 기관(CA)에서 발급된 건지 확인
  2. 인증서가 변조되지 않았는지 검증 (디지털 서명 확인)
  3. 유효기간과 도메인 일치 여부 확인

이렇게 검증을 마치면 서버의 공개키를 신뢰할 수 있게 되고, 그 공개키와 서버와 클라이언트가 주고받은 난수를 바탕으로 세션키를 생성하게 된다.

 

3. 비밀 정보 전송 및 암호화 (Pre-Master Secret) - ECDHE 방식

서버 인증서 검증이 끝나면, 원래 구식 RSA방식의 경우 클라이언트가 서버에게만 비밀 정보를 전송하지만 요즘 자주 쓰이는 ECDHE 방법으로 설명하겠다.

1. 서로의 공개키를 공유한다. (클라이언트의 공개키 : a, 서버의 공개키 : b)

2. 비밀키와 상대 공개키를 조합해 같은 Pre-Master Secret을 계산 (클라이언트의 비밀키 : x, 서버의 비밀키 : y)

  • client의 pre-master Secret : b ^ x
  • server의 pre-master Secret : a ^ y

3. 두 pre-master Secret은 실제로는 어떤 큰 수로 나눈 나머지를 구하면 같은 값이 나오도록 설정이 되어있다. 그래서 두 값이 같도록 각자가 확인한다.

4. 생성된 pre-master Secrete와 주고받은 client와 sercer의 난수(Random Number) 바탕으로 세션키를 생성한다.

Session Key = PRF(Pre-Master Secret, Client Random + Server Random)

 

4. Finished Message

 

마지막으로 서버와 클라이언트는 "지금까지의 핸드셰이크 내용이 정상인지 확인했어요." 처음으로 암호화된 메시지를 주고받으면서 중간에 공격자가 침입하지 않았는지 확인한다.

 

5. 암호화된 데이터 통신 시작 (HTTPS 본격 시작)

  • 클라이언트 → 서버 : 암호화된 HTTP 요청 (예: 로그인 요청)
  • 서버 → 클라이언트 : 암호화된 HTTP 응답 (예: 로그인 성공)

이렇게 https가 동작하는 방식에 대해서 알아봤다.

다음 글에서는 어떻게 로컬 환경에서 https를 테스트하고 코드로 구현할 수 있는지 알아보도록 하겠다.