본문 바로가기
보안

사설 인증서 발급하기

by 안드레날린 2026. 3. 20.

1. 흐름 이해

1. CA 개인키 생성
2. CA 인증서 생성
3. 서버 개인키 생성
4. 서버 CSR 생성
5. CA가 CSR을 서명해서 서버 인증서 발급
6. 서버 인증서 + CA 인증서를 묶어 fullchain 생성
7. nginx/apache 등에 적용
8. 클라이언트에 ca.crt를 신뢰 저장소로 배포

 

2. 사설 CA 만들기

2-1. CA 개인키 생성

ca.key는 인증기관의 비밀키

openssl genrsa -out ca.key 4096

 

2-2. CA 인증서 생성

자기 자신의 인증서를 생성

openssl req -x509 -new -key ca.key -sha256 -days 3650 -out ca.crt

Country Name (2 letter code) [XX]: KR
State or Province Name (full name) []: Seoul
Locality Name (eg, city) []: Seoul
Organization Name (eg, company) []: MyCompany
Organizational Unit Name (eg, section) []: Infra
Common Name (e.g. server FQDN or YOUR name) []: My Private Root CA
Email Address []:
  • -x509 : CSR이 아니라 인증서를 만들겠다는 의미
  • car.crt는 CA 자신의 인증서 (즉, "나는 이런 이름의 인증기관이다")

 

3. 사설 인증서 만들기

3-1. 서버 개인키 생성

서버가 TLS 통신에 사용할 개인키

※ 실제 CA에도 보내지 않으며, CA에서도 요구하지 않음

openssl genrsa -out server.key 2048

 

3-2. 서버 CSR 만들기

방법 A. 인터랙티브 방식

CN을 입력할 수는 있지만, SAN을 넣기 불편함

openssl req -new -key server.key -out server.csr

 

방법 B. config 파일을 이용한 방식

실무에서는 보통 config 파일 방식을 많이 사용

# server-cert.cnf

[ req ]
default_bits       = 2048
prompt             = no
default_md         = sha256
distinguished_name = req_distinguished_name
req_extensions     = req_ext

[ req_distinguished_name ]
C  = KR
ST = Seoul
L  = Seoul
O  = MyCompany
OU = Infra
CN = ahndrenaline.io

[ req_ext ]
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = ahndrenaline.io
DNS.2 = www.ahndrenaline.io
DNS.3 = api.ahndrenaline.io

 

openssl req -new -key server.key -out server.csr -config server-cert.cnf
  • CN : 대표 도메인
  • SAN : 실제 접속 가능한 도메인 목록
    • 해당 인증서 하나로 보호할 수 있는 추가적인 도메인들의 리스트
    • 요즘 브라우저 / 클라이언트는 SAN을 기준으로 이름을 검증함

 

3-3. CA가 서버 CSR 서명해서 서버 인증서 발급

이제 CA가 server.csr을 보고 server.crt를 만든다.

여기서도 SAN 정보가 인증서에 제대로 들어가야 하므로, 서명 시 확장 설정을 명시해주는게 좋다.

# server-ext.cnf

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = ahndrenaline.io
DNS.2 = www.ahndrenaline.io
DNS.3 = api.ahndrenaline.io

 

openssl x509 -req \
  -in server.csr \
  -CA ca.crt \
  -CAkey ca.key \
  -CAcreateserial \
  -out server.crt \
  -days 365 \
  -sha256 \
  -extfile server-ext.cnf

 

결과

  • server.crt : CA가 server.csr을 보고 서명해서 만들어준 결과물 (즉, 서버 인증서)
  • ca.srl : CA가 인증서를 발급할 때 쓰는 시리얼 번호 기록 파일 시리얼 번호 관리 파일

 

각 옵션 의미

  • -req : 입력이 CSR이라는 뜻
  • -in server.csr : 서버의 요청서
  • -CA ca.crt : 서명에 사용할 CA 인증서
  • -CAkey ca.key : 서명에 사용할 CA 개인키
  • -CAcreateserial : 시리얼 파일 생성
  • -out server.crt : 최종 발급될 서버 인증서
  • -extfile server-ext.cnf : SAN, 용도 등의 확장 정보 반영

 

4. fullchain.pem 만들기

이제 서버 인증서와 상위 CA 인증서를 하나로 묶는다.

 

중요! 반드시 아래 순서여야 함

순서가 뒤집히면 일부 클라이언트에서 체인 검증이 꼬일 수 있음

1. 서버 인증서
2. 상위 CA 인증서

server.crt
ca.crt

 

4-1. 인증서  하나로 묶기

cat server.crt ca.crt > fullchain.pem

 

5. 클라이언트가 신뢰하도록 ca.crt 배포

사설 CA는 공인 루트 저장소에 없기 때문에 브라우저 / OS는 기본적으로 이 CA를 신뢰하지 않는다.

따라서 ca.crt를 클라이언트의 신뢰 저장소에 넣어야 한다.

 

5-1. 운영체제 별 인증서 설치

Windows

1. ca.crt 실행
2. 인증서 설치
3. "로컬 컴퓨터"
4. "신뢰할 수 있는 루트 인증 기관" 저장소에 추가

 

Rocky / RHEL / CentOS / Fedora 계열

sudo cp ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

 

Debian / Ubuntu 계열

sudo cp ca.crt /usr/local/share/ca-certificates/my-private-ca.crt
sudo update-ca-certificates

 

macOS

1. Keychain Access 열기
2. System 키체인에 ca.crt 추가
3. Trust를 Always Trust로 설정

 

6. 검증 (내용 보기)

1. 서버 인증서 내용 보기
openssl x509 -in server.crt -text -noout

2. CSR 내용 보기
openssl req -in server.csr -text -noout

3. CA 인증서 내용 보기
openssl x509 -in ca.crt -text -noout

4. 체인 검증
openssl verify -CAfile ca.crt server.crt