HTTP(HyperText Transfer Protocol)는 월드 와이드 웹(WWW)에서 데이터를 주고받기 위한 통신 프로토콜이다. HTTPS(HyperText Transfer Protocol Secure)는 HTTP의 보안 버전으로 데이터 전송 시 보안을 강화하기 위해 SSL/TLS 프로토콜을 사용.
HTTP는 클라이언트(예: 웹 브라우저)와 서버 간에 요청과 응답을 주고받는 방식으로 작동. 이때 데이터는 평문으로 전송되며 특별한 보안 처리가 없어 네트워크 상에서 데이터가 노출될 위험이 있다. 여기서 HTTPS는 SSL/TLS 암호화를 통해 데이터의 기밀성과 무결성을 보장한다.
포트는 HTTP는 기본적으로 포트 80을 사용하고 HTTPS는 포트 443을 사용한다.
URL은 http:// https://로 나뉜다.
HTTPS는 SSL/TLS 인증서를 사용하여 서버의 신원을 검증한다.
SSL(보안 소켓 계층)/TLS(전송 계층 보안)은 암호화, 인증, 무결성을 보장한다.
암호화(Encryption) : 데이터를 암호화하여 제 3자가 내용을 볼 수 없게 함.
인증(Authentication) : 서버의 신원을 검증하여 피싱 사이트 등을 방지
무결성(Integrity) : 데이터가 전송 중에 변경되지 않았음을 확인
주요 개념
공개키 암호화 : 암호화와 복호화에 서로 다른 키(공개 키와 개인 키)를 사용한다. 키 교환에 안전.
대칭키 암호화 : 동일한 키로 암호화와 복호화를 수행.
SSL/TLS 핸드쉐이크 과정
1. 클라이언트 헬로 : 클라이언트가 서버에 연결을 요청하고 지원하는 SSL/TLS 버전과 암호화 방법을 제안.
클라이언트는 다음과 같은 정보를 서버에 보냅니다.
- 지원 TLS 버전: TLS 1.2, TLS 1.1, TLS 1.0
- 지원 암호 모음 목록:
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_RSA_WITH_AES_128_CBC_SHA256
- 등등
- 클라이언트 랜덤 난수: abc123...
서버는 클라이언트의 요청에 응답
- 선택한 TLS 버전: TLS 1.2
- 선택한 암호 모음: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- 서버 랜덤 난수: def456...
- 서버 인증서 전송
SSL/TLS 인증서는 신뢰할 수 있는 기관(인증 기관, CA)에서 발급. 인증서는 서버의 공개 키와 신원을 포함하며, 클라이언트는 이를 통해 서버의 진위를 확인할 수 있다.
HTTPS의 장점
데이터 암호화를 통해 개인정보 유출을 방지. 사용자에게 신뢰를 제공하여 사이트 이미지 개선. 구글 등 검색 엔진은 HTTPS 사이트를 우선적으로 노출. 최신 브라우저는 HTTP 사이트에 대해 경고 메시지 표시.
현재 성능면에서도 SSL/TLS 프로토콜의 개선으로 HTTP 와 별반 차이가 없음.
Java와 Spring을 사용하는 신입 또는 취업 준비 중인 백엔드 개발자가 HTTP와 HTTPS의 차이점 및 SSL/TLS의 작동 원리를 이해하고 실습해볼 수 있는 내용을 단계별로 정리해보았습니다.
목표: Spring Boot 애플리케이션에 HTTPS를 활성화하여 SSL/TLS를 사용하는 환경을 구성합니다.
SSL 인증서 생성
개발 환경에서는 자기 서명 인증서(Self-Signed Certificate)를 생성하여 사용할 수 있습니다.
keytool -genkeypair -alias myserver -keyalg RSA -keysize 2048 -keystore keystore.p12 -storetype PKCS12 -validity 365
alias: 키의 이름 (여기선 myserver).keystore.p12: 생성된 키스토어 파일.-validity 365: 인증서 유효 기간 365일.Spring Boot 설정 파일 수정
application.yml 또는 application.properties 파일에 SSL 설정을 추가합니다.
server:
port: 8443
ssl:
enabled: true
key-store: classpath:keystore.p12
key-store-password: mypassword
key-alias: myserver
HTTPS로 애플리케이션 실행
애플리케이션 실행 후 브라우저에서 https://localhost:8443로 접속하여 SSL/TLS를 통한 HTTPS 연결을 테스트합니다.
브라우저에서 경고가 뜨는 이유는 자기 서명 인증서이기 때문입니다.
추가 과제
목표: 클라이언트도 인증서를 사용하여 서버와 상호 인증하는 환경을 설정합니다.
클라이언트 인증서 생성
keytool -genkeypair -alias client -keyalg RSA -keysize 2048 -keystore client_keystore.p12 -storetype PKCS12 -validity 365
서버의 신뢰 저장소에 클라이언트 인증서 등록
클라이언트 인증서를 서버의 신뢰 저장소에 추가합니다.
keytool -export -alias client -file client_cert.cer -keystore client_keystore.p12
keytool -import -alias client -file client_cert.cer -keystore server_truststore.p12
Spring Boot 설정 추가
application.yml에서 SSL 설정에 client-auth 옵션을 추가합니다.
server:
ssl:
client-auth: need
trust-store: classpath:server_truststore.p12
trust-store-password: mypassword
테스트
목표: HTTPS 환경에서 RESTful API를 개발하고, 클라이언트를 통해 이를 호출합니다.
RESTful API 개발
간단한 CRUD API를 Spring Boot로 구현합니다.
HTTPS로 API 호출
curl을 사용하여 HTTPS로 API를 호출합니다.Java 클라이언트 구현
Java의 RestTemplate 또는 WebClient를 사용하여 HTTPS 요청을 보냅니다.
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(new File("truststore.p12"), "password".toCharArray())
.build();
HttpClient client = HttpClients.custom().setSSLContext(sslContext).build();
RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory(client));
String response = restTemplate.getForObject("https://localhost:8443/api/resource", String.class);
System.out.println(response);
목표: HTTPS와 HTTP 환경에서의 성능 차이를 측정하고 최적화 방안을 적용합니다.
HTTP/HTTPS 환경 구성
동일한 애플리케이션을 HTTP와 HTTPS 포트에서 각각 실행합니다.
성능 측정
ab)를 사용하여 각각의 요청 처리 속도와 응답 시간을 측정합니다.ab -n 1000 -c 100 http://localhost:8080/
ab -n 1000 -c 100 https://localhost:8443/HTTP/2 활성화
HTTPS를 사용하면 HTTP/2 프로토콜을 활성화할 수 있습니다. application.yml에 다음 설정을 추가합니다.
server:
http2:
enabled: true
최적화
목표: SSL/TLS 보안 설정을 점검하고, HTTPS 환경에서의 취약점을 분석합니다.
SSL Labs를 통한 보안 점검
취약한 프로토콜/암호화 알고리즘 비활성화
application.yml에서 TLS 1.0 및 1.1을 비활성화합니다.server:
ssl:
enabled-protocols: TLSv1.2,TLSv1.3
실습 결과 분석
목표: 인증서 만료로 인한 서비스 중단을 방지하기 위해 인증서를 자동으로 갱신하는 방법을 익힙니다.
Let's Encrypt로 인증서 발급
Certbot을 사용하여 무료 인증서를 발급받습니다.
sudo certbot certonly --standalone -d yourdomain.com
갱신 스크립트 작성
인증서를 자동으로 갱신하는 스크립트를 작성합니다.
sudo certbot renew
Spring Boot 무중단 갱신
목표: HTTPS 설정 시 발생할 수 있는 문제를 파악하고 해결하는 경험을 쌓습니다.