본문 바로가기
Back-End

Spring Boot 프로젝트 local 환경에서 https 적용하기

by newny 2024. 5. 31.
반응형

Intro


현재 진행중인 프로젝트의 https 개발환경을 목적으로 자체 서명된 인증서로 https를 적용해 보았다. https란 무엇이며, https 연결 설정 과정과 로컬 프로젝트에 https를 적용하는 방법에 대해서 설명하겠다.

 
 
 

https란?


HTTPS(HyperText Transfer Protocol Secure)는 HTTP 프로토콜을 기반으로 한 웹 통신 프로토콜이다. HTTPS는 데이터를 암호화하여 보안을 강화하며, 이를 위해 SSL(Secure Sockets Layer) 또는 최신 버전의 TLS(Transport Layer Security) 프로토콜을 사용한다.
 
 
 
 

https 연결 설정 과정


TLS Handshake 시작

  • 클라이언트가 HTTPS로 접속하려는 서버에 연결을 시도
  • 서버는 클라이언트의 연결 요청을 받고, TLS Handshake 프로세스를 시작

출처 : https://www.cloudflare.com/ko-kr/learning/ssl/what-happens-in-a-tls-handshake/

SSL (Secure Sockets Layer)와 TLS (Transport Layer Security)는 암호화 통신을 위한 프로토콜이다. SSL은 초기 버전들이며, TLS는 SSL의 후속 버전으로 개발되어 보안과 안정성을 더욱 강화했다. 현재 대부분의 운영 시스템에서는 TLS를 사용하며, SSL은 보안 결함이 있기 때문에 사용되지 않는다.
TLS는 SSL 버전 3.0부터 시작되어 현재는 TLS 1.2 및 TLS 1.3가 널리 사용된다. TLS 1.2와 TLS 1.3는 최신 웹 브라우저와 웹 서버에서 지원되며, HTTPS 연결에서 사용된다.

 

서버 인증

  • 서버는 클라이언트에게 자신의 인증서를 전송
  • 이 인증서는 공개 키와 서버의 정보(도메인, 인증 기관 등)를 포함
일반적으로 인증서 파일에는 공개키(public key)와 개인키(private key)의 쌍이 포함된다. 이 두 개의 키는 함께 생성되며, 서로 짝이 맞는 키 쌍이다.
서버에서 클라이언트에게 인증서를 전송할 때는 개인키는 제외하고 공개키와 서버의 정보만을 포함하여 보낸다.

 

인증서 검증

  • 클라이언트는 서버로부터 받은 인증서를 검증
  • 검증 과정에서 다음을 확인함
    • 인증서의 유효 기간 확인
    • 인증서 발급 기관(CA)의 신뢰 여부 확인
    • 인증서가 요청한 도메인의 것인지 확인
웹 브라우저는 내부에 내장된 인증 기관(Certificate Authority, CA) 목록을 가지고 있다. 이 목록은 신뢰할 수 있는 인증 기관(CA)들의 공개 키를 포함하고 있어서, 클라이언트가 서버로부터 받은 인증서의 유효성을 검증할 때 사용된다.

 

세션 키 생성

  • 클라이언트는 서버와 안전하게 통신하기 위해 사용할 세션 키를 생성
  • 세션 키는 서버의 공개 키를 사용하여 암호화

 

암호화된 세션 키 전송

  • 클라이언트는 서버의 공개 키를 사용하여 생성한 세션 키를 서버에 전송

 

세션 키 복호화

  • 서버는 자신의 개인 키를 사용하여 클라이언트가 전송한 세션 키를 복호화
공개키와 개인키의 관계는 비대칭키 암호화 방식에서 사용되며, 대표적으로 RSA 알고리즘에서 설명할 수 있다.
RSA 알고리즘에서는d는 e에 대한 역원으로 구성된다. 따라서 공개키(e,N)로 암호화된 데이터는 개인키(d,N)로만 해독할 수 있고, 개인키(d,N)로 암호화된 데이터는 공개키(e,N)로만 해독할 수 있다.

 

암호화된 통신

  • 이후 클라이언트와 서버 간의 통신은 서로 암호화된 세션 키를 사용하여 이루어짐
  • 이 과정에서는 SSL 또는 TLS 프로토콜을 사용하여 데이터가 암호화됨

 

HTTPS 연결 확립

  • 클라이언트는 인증서 검증과 세션 키 교환 과정이 성공적으로 완료되면 HTTPS 연결이 확립됨
  • 이제 클라이언트와 서버 간의 안전하고 암호화된 통신이 가능해짐
HTTPS 연결에서의 인증 과정은 클라이언트가 웹 페이지에 접근할 때 한 번만 이루어진다. 이후에는 세션을 통해 데이터를 주고받을 수 있다.

 
 
 
 

자체 서명 인증서(Self-signed certificate) 만들기


개인키와 인증서 생성

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
  • openssl: OpenSSL 명령어를 사용 (OpenSSL은 암호화와 관련된 다양한 작업을 수행할 수 있는 오픈 소스 라이브러리와 도구 모음)
  • req: Certificate Signing Request(CSR)를 생성하거나 관리하는 OpenSSL 명령어 서브셋을 사용한다는 것을 의미
  • -x509: X.509 형식의 셀프 사인된 인증서를 생성한다는 옵션 (자체 서명된 인증서를 의미)
  • -newkey rsa:4096: 새로운 RSA 알고리즘 키 쌍을 생성하는 옵션 (4096은 키의 길이)
  • -keyout key.pem: 생성된 개인 키(private key)를 key.pem 파일에 출력하는 옵션
  • -out cert.pem: 생성된 인증서를 cert.pem 파일에 출력하는 옵션
  • -days 365: 인증서의 유효 기간을 설정하는 옵션 (365일로 설정)
위 명령어는 OpenSSL을 사용하여 RSA 알고리즘을 사용해 4096비트 길이의 새로운 개인 키와 이에 대응하는 셀프 사인된 X.509 형식인증서를 생성하며, 개인 키를 key.pem 파일에, 인증서를 cert.pem 파일에 각각 1년 동안 유효하도록 저장하는 명령어이다.

 
위의 명령어를 입력하면 다음 단계를 거친다.

  • Enter PEM pass phrase:
    비밀번호를 입력, 이 비밀번호는 개인 키 파일을 암호화하는 데 사용
  • Verifying - Enter PEM pass phrase:
    비밀번호 재확인
  • Country Name (2 letter code) [AU]:
    국가 코드를 입력 (대한민국은 "KR"), 기본값을 사용하려면 Enter
  • State or Province Name (full name) [Some-State]:
    주 또는 도 이름을 입력, 기본값을 사용하려면 Enter
  • Locality Name (eg, city) []:
    도시 이름을 입력, 기본값을 사용하려면 Enter
  • Organization Name (eg, company) [Internet Widgits Pty Ltd]:
    조직 이름을 입력, 기본값을 사용하려면 Enter
  • Organizational Unit Name (eg, section) []:
    조직의 부서 이름을 입력, 기본값을 사용하려면 Enter
  • Common Name (e.g. server FQDN or YOUR name) []:
    도메인 이름 또는 로컬 호스트 이름을 입력 (로컬 테스트용이므로 "localhost"를 입력)
  • Email Address []:
    이메일 주소를 입력, 기본값을 사용하려면 Enter

 

keystore 생성

openssl pkcs12 -export -in cert.pem -inkey key.pem -out keystore.p12 -name tomcat
  • openssl: OpenSSL 명령어를 사용
  • pkcs12: PKCS#12 형식은 개인 키와 인증서를 하나의 파일에 포함하는 형식
  • -export: 출력 파일에 개인 키와 인증서를 내보내는 옵션
  • -in cert.pem: 인증서 파일을 지정하는 옵션 (cert.pem 파일에서 인증서를 읽어옴)
  • -inkey key.pem: 개인 키 파일을 지정하는 옵션 (key.pem 파일에서 개인 키를 읽어옴)
  • -out keystore.p12: 출력 파일의 이름을 지정하는 옵션 (keystore.p12 파일에 결과를 출력)
  • -name tomcat: 내보낸 개인 키와 인증서에 지정할 이름을 지정하는 옵션 (아무 이름이나 상관없음)
위 명령어는 cert.pem 파일 key.pem 파일에서 읽은 인증서와 개인 키를 하나의 PKCS#12 형식 파일keystore.p12에 내보내며, 그 파일에는 "tomcat"이라는 이름이 지정됩니다.

 
위의 명령어를 입력하면 다음 단계를 거친다.

  • Enter pass phrase for key.pem:
    앞서 설정한 비밀번호 입력
  • Enter Export Password:
    .p12 파일을 보호할 비밀번호를 입력
  • Verifying - Enter Export Password:
    비밀번호 재확인

 
 
 
 

https 적용하기


application.yml 설정

server:
  port: 8443
  ssl:
    enabled: true # SSL/TLS를 활성화
    key-store: ${KEYSTORE_PATH}
    key-store-password: ${YOUR_EXPORT_PASSWORD}
    key-store-type: PKCS12
    key-alias: ${KEYSTORE_NAME}

 위와 같이 설정해 주면 https를 사용하여 통신할 수 있다.
 
이제 프로젝트를 실행시킨 후 https://localhost:8443 으로 접속하여 연결이 되는지 확인해보자.

연결은 됐지만 자체 서명된 인증서이므로 인증서가 올바르지 않다고 뜬다. (정상임)
개발자 도구로 들어가서 보안탭으로 들어가면 연결 프로토콜을 확인할 수 있다.

결론


자체 서명된 인증서를 사용하여 https 통신을 설정해보니 그 과정들이 더 잘 이해되었다. https 적용은 굉장히 멀게만 느껴졌었는데 과정을 정리해보니 크게 어려울게 없는것 같다.
 
 
 
 

출처

영혼의 단짝 ChatGPT

반응형

'Back-End' 카테고리의 다른 글

JaCoCo 적용기  (0) 2024.06.13
Mapstruct 적용기  (0) 2024.05.16
자동 배포로 한걸음 다가가기 - 빌드 관리 도구 Gradle  (0) 2024.01.05

댓글