암호화 기초 개념
단방향 암호화
단방향 암호화의 특징은 암호화만 가능하고 복호화는 불가능한 특징을 갖는다. 비밀번호 저장(SHA-256)이나 세션/토큰(해시 함수)을 만들 때 사용하며 한 번 암호화하면 원본으로 되돌리 수 없다
양방향 암호화
양방향 암호화의 특징은 암호화와 복호화 모두가 가능하다
- 암호화: 평문 + 비밀키 → 암호문
- 복호화: 암호문 + 비밀키 → 평문
특징
- 암호화와 복호화에 동일한 키 사용
- 키를 안전하게 공유해야 하는 문제 발생
- 빠른 처리 속도
비대칭키 방식 (공개키 암호화)
- 키 생성: 공개키(Public Key) + 비밀키(Private Key)
- 암호화: 평문 + 공개키 → 암호문
- 복호화: 암호문 + 비밀키 → 평문
주요 알고리즘으로는 RSA와 ECDSA 등이 있으며 활용 사례로는 비트코인이나 HTTPS 통신이 있다
HTTPS 통신과 SSL/TLS 인증서
HTTPS 통신 원리
[사용자 접속]
사용자가 https://server.example.com 접속
↓
[인증서 전달]
서버가 SSL/TLS 인증서를 브라우저에 전송
(인증서에는 공개키가 포함됨)
↓
[데이터 암호화]
브라우저가 공개키로 데이터를 암호화
↓
[암호문 전송]
암호화된 데이터를 서버로 전송
↓
[데이터 복호화]
서버가 비밀키로 암호화된 데이터를 복호화
HTTPS가 필요한 이유
HTTP의 문제점
- GET 파라미터로 전송할 경우 URL에 노출이 되어서 위험도가 높다
- POST Body로 전송할 경우 URL에는 안 보이지만 암호화가 안 되어 위험도가 높다
HTTPS는 모든 데이터를 암호화 한다
중요: <form> 태그나 axios를 통한 POST 요청도 HTTPS 없이는 평문으로 전송된다
인증서 발급 프로세스
수동 발급 프로세스 (일반적인 방법)
1. 서버에서 공개키/비밀키 생성
↓
2. 공개키 + 서버 정보로 CSR 생성
(Certificate Signing Request)
↓
3. CA 기관에 CSR 제출
↓
4. CA가 도메인 소유 여부 검증
↓
5. CA가 디지털 서명하여 인증서 발급
↓
6. 서버에 인증서 설치
Kubernetes 자동화 프로세스
1. ClusterIssuer 생성 (CA 기관 지정)
↓
2. Certificate 생성 (도메인 정보)
↓
3. cert-manager가 자동으로
- 공개키/비밀키 생성
- CSR 생성
- CA에 제출
- 도메인 검증 처리
- 인증서 발급
- Secret에 저장
↓
4. Ingress가 Secret 참조하여 HTTPS 활성화
Kubernetes 인증서 관리 구조
핵심 구성 요소
- ClusterIssuer: CA 기관 및 인증서 종류를 지정하여 선언적 리소스 타입이다
- Certificate: 도메인 정보 및 발급 요청을 하며 선언적 리소스 타입이다
- cert-manager: 실제 발급 작업을 수행하하며 컨트롤러 (실행 프로그램)이다
비유
Ingress : Ingress Controller
‖
ClusterIssuer, Certificate : cert-manager
cert-manager의 역할
- Certificate 리소스 모니터링
- 공개키 / 비밀키 자동 생성
- CSR 생성 및 CA 제출
- 도메인 소유권 검증 처리
- 발급된 인증서를 Secret에 저장
- 인증서 만료 전 자동 갱신
cert-manager 설치
namespace 생성
kubectl create namespace cert-manager # 성공 메시지 namespace/cert-manager created
중요: Namespace 이름은 반드시 cert-manager 여야 한다. 다른 이름 사용 시 설치에 실패한다.
cert-manager CRDs 설치
CRDs(Custom Resource Definitions): cert-manager가 작동하기 위한 기반 구조
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.5.0/cert-manager.crds.yaml
설치되는 리소스
- Issuer, ClusterIssuer 리소스 타입 정의
- Certificate 리소스 타입 정의
- 기타 cert-manager 관련 리소스 정의
cert-manager 본체 설치
cert-manager 프로그램 (Pod, Deployment 등) 설치
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.5.0/cert-manager.yaml
설치되는 구성 요소
- cert-manager Pod(실제 작업 수행)
- cert-manager Deployment
- cert-manager Service
- 필요한 RBAC(Role-Based Access Control) 설정
ClusterIssuer 설정
ClusterIssuer YAML
https.yml (첫 번째 부분)
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: my-issuer
namespace: hyeok # 본인의 namespace로 변경
spec:
acme:
# CA 서버 주소 - Let's Encrypt 사용
server: https://acme-v02.api.letsencrypt.org/directory
# 인증서 만료 알림 이메일
email: your-email@gmail.com # 실제 이메일로 변경
privateKeySecretRef:
# CA 통신용 Secret 이름
name: my-issuer
solvers:
- http01:
ingress:
# nginx 기반 Ingress Controller 사용
class: nginx
설정 항목 설명
- name: ClusterIssuer 이름으로 Certificate에서 참조
- server: Let’s Encrypt CA 서버 주소
- email: 인증서 만료 알림 수신 이메일 (실제 이메일 주소 필수)
- privateKeySecretRef.name: CA 통신용 키 저장 Secret (자동 생성됨)
- solvers.http01.ingress.class: 도메인 검증 방식 (nginx Ingress Controller 사용)
Let’s Encrypt는 무료 SSL/TLS 인증서 발급 기관으로 자동화된 인증서 발급을 지원해주며 전 세계적으로 신뢰받는 CA(Certificate Authority)이다
Certificate 설정
Certificate YAML
https.yml (두 번째 부분)
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: server-hyeok4444-com-tls
namespace: hyeok # 본인의 namespace로 변경
spec:
# 인증서가 저장될 Secret 이름 (Ingress와 일치 필수!)
secretName: server-hyeok4444-com-tls
duration: 2160h # 90일
renewBefore: 360h # 만료 15일 전 갱신
issuerRef:
name: my-issuer # ClusterIssuer 이름과 일치
kind: ClusterIssuer
commonName: server.hyeok4444.shop
dnsNames:
- server.hyeok4444.shop # 본인의 도메인으로 변경
- metadata.name: Certificate 리소스 이름
- secretName: 매우 중요하며 Ingress의 secretName와 일치해야 한다
- duration: 인증서 유효 기간
- renewBefore: 만료 며칠 전에 갱신할 지
- issuerRef.name: ClusterIssuer 이름 참조
- commonName: 대표 도메인
- dnsNames: 인증서에 포함할 모든 도메인
여러 서브 도메인 추가
dnsNames: - server.hyeok4444.shop - api.hyeok4444.shop - admin.hyeok4444.shop
Ingress와 Certificate 연동
Ingress YAML (HTTPS 설정 포함)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: order-backend-ingress
namespace: hyeok
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: my-issuer
spec:
tls:
- hosts:
- "server.hyeok4444.shop"
# Certificate의 secretName과 정확히 일치해야 한다
secretName: server-hyeok4444-com-tls
rules:
- host: server.hyeok4444.shop
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ordersystem-backend-service
port:
number: 80
핵심 연결 포인트
1. Certificate 리소스가 인증서 발급
↓
2. server-hyeok4444-com-tls Secret에 저장
↓
3. Ingress가 해당 Secret 참조
↓
4. HTTPS (443 포트) 자동 활성화
인증서 발급 및 확인
리소스 배포
kubectl apply -f https.yml #예상 출력 clusterissuer.cert-manager.io/my-issuer created certificate.cert-manager.io/server-hyeok4444-com-tls created
Certificate 상태 확인
kubectl get certificate -n hyeok # 정상 상태 NAME READY SECRET AGE server-hyeok4444-com-tls True server-hyeok4444-com-tls 5m
READY 컬럼 의미
- True: 인증서 발급 성공, Secret에 저장되며 정상 처리
- False: 발급 진행 중 또는 실패로 describe 명령어로 확인 필요
문제 발생 시 확인
- Waiting for http-01 challenge: 도메인 검증 실패로 Route53, Ingress 설정을 확인해봐야 한다
- Self check failed: HTTP 라우팅이 안 된 것으로 Ingress로 HTTP 접속 테스트를 해봐야 한다
- Invalid email: 이메일 형식 오류로 실제 이메일 주소를 사용해야 한다
도메인 검증 프로세스
CA가 도메인 소유권을 확인하는 방법
1. Let's Encrypt가 HTTP 요청 전송
GET http://server.hyeok4444.shop/.well-known/acme-challenge/xxx
↓
2. 요청이 Route53 → Load Balancer → Ingress Controller를 거쳐 도달
↓
3. cert-manager가 임시 응답 제공
↓
4. Let's Encrypt가 응답 확인 → 소유권 인정
↓
5. 인증서 발급
중요: 인증서 발급 전에 HTTP 통신이 정상적으로 작동해야 한다
Secret 확인
kubectl get secret -n hyeok # 예상 출력 NAME TYPE DATA AGE my-app-secrets Opaque 2 22h server-hyeok4444-com-tls kubernetes.io/tls 2 5m
HTTPS 테스트
Postman 테스트
헬스체크
GET https://server.hyeok4444.shop/health
→ 응답: "ok"
로그인
POST https://server.hyeok4444.shop/member/doLogin
Headers:
Content-Type: application/json
Body:
{
"email": "admin@example.com",
"password": "12341234"
}
→ 응답: { "token": "..." }
브라우저 테스트
HTTP VS HTTPS 비교
- http://server.hyeok4444.shop는 ⚠️ 안전하지 않고 암호화가 안 됨
- https://server.hyeok4444.shop는 🔒 자물쇠 아이콘이며 암호화됨
브라우저에서 확인
- https://server.hyeok4444.shop 접속
- 주소창에 자물쇠 아이콘 클릭
- 인증서 정보 확인 가능
http

https

HTTPS 동작 원리
접속
사용자가 https://server.hyeok4444.shop 입력
인증서 다운로드
브라우저가 서버로부터 SSL/TLS 인증서 수신(이 인증서는 Ingress가 Secret에서 가져옴)
인증서 검증
브라우저가 인증서의 유효성 확인
- Let’s Encrypt CA가 서명 했는지 확인
- 도메인이 일치하는지 확인
- 만료되지 않았는지 확인
암호화 통신 시작
브라우저가 인증서의 공개키로 데이터 암호화
암호화된 데이터 전송
- POST / member/create
- BODY: (암호화된 데이터)
서버에서 복호화
서버가 비밀키로 데이터 복호화
응답도 암호화
서버 응답도 암호화하여 전송
전체 구조도
사용자 ↓ HTTPS 요청 Route53 ↓ Load Balancer ↓ Ingress Controller ↓ (Secret의 인증서 사용) ├─ 인증서 제공 (최초 접속 시) └─ 암호화된 데이터 복호화 ↓ Service ↓ Pod (Spring)