로컬 Root CA 를 보관하면서 서버·클라이언트 인증서를 발급하고, 발급 이력을 추적하고, 필요한 포맷으로 변환하는 독립 실행형 도구. Terminal UI를 통해 조금은 편하게 작업할 수 있다.
0. 개인키 생성·관리 미리 만들어 두고 1·2 에서 골라 쓴다. 패스프레이즈 제거도 여기서
1. rootCA 생성 키 선택 → ① 등록된 키 ② 즉석 생성
2. 인증서 발급 CA 선택 → ① cert_gen 이력에서 고르기 ② rootCA 가 있는 디렉터리 입력
키 선택 → ① 등록된 키 ② 즉석 생성
3. 인증서 변환 대상 → ① 발급 이력에서 고르기 ② 외부 인증서 파일 지정
4. 발급 이력·만료 조회 목록 → 상세 / 검증 / 번들 추출 / 갱신 / 폐기 / CRL
5. 서버에 CA 신뢰 등록 OS 신뢰 저장소 + Java 트러스트스토어. 등가 명령도 함께 제공
여기 github 리포에서 다운로드한다.
설치과정 없는 독립 실행형 바이너리. Redhat 계열 (8.x-10.x), Debian 계열 (12,13, Ubuntu22,23,24), Windows 10,11(Server 2019이상)을 지원한다.
windows defender에서 trojan 으로 검출된다. 의도적으로 나쁜 짓 안했다. 의심스러우면 안쓰면 된다.
cert-gen --help 명령으로 사용법을 확인할 수 있다.
cert-gen 0.1.0 — 자가서명 인증서 생성기 (로컬 CA)
사용법:
cert-gen [전역 옵션] <명령> [하위 명령] [옵션]
전역 옵션:
--data-dir DIR 상태 디렉터리 (기본: <현재 디렉터리>/cert-gen-data)
-c, --config FILE 설정 파일 (기본: <상태 디렉터리>/config.toml)
--json 결과를 JSON 으로 출력
-q, --quiet 사람이 읽는 출력을 생략
-v, --version 버전 출력
명령:
init 상태 디렉터리와 DB 를 만든다
where 상태 디렉터리 위치와 규칙을 보여 준다
doctor 환경 점검 (권한·DB·CA·만료·CRL·openssl). --deep 으로 번들 해시까지
key create --name NAME 개인키를 만들어 둔다 (CA·발급에서 고를 수 있다)
key list 개인키 목록 (쌍 토큰으로 인증서와 짝을 맞춘다)
key show NAME 개인키 상세·사용처
key import --file FILE 외부 개인키를 가져온다
key passphrase NAME 패스프레이즈 설정/제거(--remove)
key delete NAME 개인키 삭제 (쓰이는 중이면 거부)
ca create Root CA 를 만든다 (--cn 필수, --org/--ou/--country)
ca list CA 목록
ca show SLUG CA 상세
ca export SLUG ca.crt 를 내보낸다 (클라이언트 신뢰 등록용)
ca adopt --dir DIR 외부 CA 를 복사 없이 등록해 발급에 쓴다
ca import --key K --cert C 외부 CA 를 상태 디렉터리로 복사해 등록한다
apply FILE... openssl .cnf 를 읽어 CA 생성·발급을 한 번에
(한 파일에 --- 로 블록을 나누거나, 파일을 여러 개 주거나)
cert issue 인증서를 발급한다 (--config 로 openssl .cnf 입력 가능)
cert list 발급 이력
cert show REF 상세 (ID | serial | CN)
cert renew REF 갱신 (기본: 새 키)
cert revoke REF 폐기하고 CRL 을 다시 만든다
cert verify REF 검증 (체인·호스트명·폐기)
cert bundle REF 번들 zip 을 꺼낸다
csr create 외부 CA 제출용 CSR 을 만든다
csr sign --csr FILE 받은 CSR 을 우리 CA 로 서명한다
export p12 REF PKCS#12
export jks REF Java KeyStore
export der REF DER
export pem REF PEM (cert/key/fullchain/ca)
export k8s REF kubernetes.io/tls Secret (+ Ingress)
crl generate SLUG CRL 을 다시 만든다
crl list SLUG 폐기 목록
backup create 상태 디렉터리 전체를 tar.gz 로 묶는다 (CA 개인키 포함)
backup restore FILE 백업을 복원한다 (--dry-run 으로 먼저 확인)
trust show [SLUG] OS·Java 신뢰 저장소 등록 명령을 만든다
tui 터미널 UI 를 띄운다
비밀값은 명령행 인자로 받지 않는다 (/proc/<pid>/cmdline 노출).
환경변수나 --*-stdin 옵션, 또는 TTY 프롬프트를 쓴다.
CERT_GEN_CA_PASSPHRASE, CERT_GEN_EXPORT_PASSWORD, CERT_GEN_KEY_PASSPHRASE
'cert-gen <명령> -h' 로 각 명령의 옵션을 본다.
기본적으로 cert-gen key create --name ca-key --algo ec-p384 --passphrase-stdin 처럼 명령을 넣어야 하는데 이렇게 명령줄 만드는게 귀찮아서 만든 도구로써
cert-gen tui
를 입력하면 terminal UI를 사용할 수 있다.
| 항목 | 내용 |
|---|---|
| 발급 범위 | 로컬 Root CA → leaf 1단계 (Intermediate 생성 제외) |
| 프로필 | server(기본) · client · server+client |
| 키 알고리즘 | RSA 2048/3072/4096 · EC P-256/P-384 · Ed25519 |
| 상태 | 발급 이력·serial → SQLite / 키·번들 → 상태 디렉터리(기본 ./cert-gen-data) |
| CA 키 보호 | 패스프레이즈 암호화 PKCS#8 기본. 서명할 때 입력 |
| 출력 | PEM(key/cert/chain/fullchain/ca) 기본. 요청 시 PKCS#12·JKS·DER·K8s tls Secret |
CA 키와 서버/클라이언트 키는 보호 요구가 다르다.
key list 의 보호 열이 이 상태를 한눈에 보여 준다 — 암호 / 평문 / 암호+평문(묶음).
# 바이너리를 PATH 에 두고 상태 디렉터리를 만든다
cert-gen init
# 환경 점검 (권한·DB·CA·만료·CRL·openssl/keytool)
cert-gen doctor
패스프레이즈는 명령행 인자로 받지 않는다(프로세스 목록 노출 방지). 세 경로만 쓴다.
| 경로 | 방법 |
|---|---|
| 환경변수 | CERT_GEN_CA_PASSPHRASE (CA 키) · CERT_GEN_KEY_PASSPHRASE (등록 키) · CERT_GEN_EXPORT_PASSWORD (키스토어) |
| stdin | --passphrase-stdin / --key-passphrase-stdin |
| TTY 프롬프트 | 대화형 실행 시 자동으로 묻는다 |
아래 화면의
••는 환경변수에 넣은 패스프레이즈를 가린 표시다.
CA 키(암호) → Root CA → 서버 키 A(암호) → 인증서 A → 복호화 동반본 A′ → 인증서 B(무인)
미리 만든 등록 키로 CA 를 만들면, 그 CA 는 키를 참조만 하므로 키 교체·감사 추적이 쉽다.
CERT_GEN_KEY_PASSPHRASE=•• cert-gen key create ca-key --encrypt --key-algo ec-p384
CERT_GEN_KEY_PASSPHRASE=•• cert-gen ca create --cn "HD Root CA" --org HaeDong --country KR --key ca-key

발급할 때 키 패스프레이즈(CERT_GEN_KEY_PASSPHRASE)와 CA 패스프레이즈
(CERT_GEN_CA_PASSPHRASE)를 각각의 환경변수로 넘긴다.
CERT_GEN_KEY_PASSPHRASE=•• cert-gen key create svc-key --encrypt --key-algo rsa2048
CERT_GEN_KEY_PASSPHRASE=•• CERT_GEN_CA_PASSPHRASE=•• \
cert-gen cert issue --ca hd-root-ca --key svc-key \
--cn web.example.com --san '*.web.example.com' --san 10.0.0.5

key decrypt 가 같은 키쌍의 평문 동반본을 만든다. 이후 --decrypted 로 발급하면
키 패스프레이즈를 묻지 않는다(무인 서버용). CA 패스프레이즈만 필요하다.
CERT_GEN_KEY_PASSPHRASE=•• cert-gen key decrypt svc-key
CERT_GEN_CA_PASSPHRASE=•• \
cert-gen cert issue --ca hd-root-ca --key svc-key --decrypted \
--cn web2.example.com --san web2.example.com

key list 의 보호 열이 암호+평문 이면 묶음이 구성된 것이다. 쌍 토큰이 같은
두 항목(또는 인증서)은 같은 키쌍이다.

CA 키로는
key decrypt가 거부된다.ca create --key도 평문 동반본이 있는 키는
거부한다 — "CA 개인키는 평문 사본을 두지 않는다"는 불변식을 코어가 강제한다.
손에 익은 openssl 설정(.cnf) 형식을 그대로 읽어 CA + leaf 를 한 번에 만든다.
한 파일 안에 --- 로 CA 블록과 leaf 블록을 나눈다. SAN 은 [alt_names] 블록에 선언한다.
한 번의
apply는 CA 1개만 만든다(CA:서버/클라이언트 = 1:N). CA 블록이 여러 개면
거부한다.
CERT_GEN_CA_PASSPHRASE=•• cert-gen apply pki.cnf
cert-gen cert list --ca hd-apps-ca

keyUsage·EKU 는 cert-gen 의 프로필이 결정한다..cnf의 확장은 프로필 추론
(CA:TRUE → CA, serverAuth/clientAuth → server/client)에만 쓰이고 그대로 복사되지 않는다.
구조적으로 잘못된 확장 조합을 막기 위해서다.
Windows 인증서 저장소나 IIS 는 PKCS#12(.pfx)를 쓴다. export p12 --ca <slug> 는
CA 개인키 + 인증서를 함께 담은 pfx 를 만든다(등록 키를 쓰는 CA 도 자동 해석).
CERT_GEN_KEY_PASSPHRASE=•• CERT_GEN_EXPORT_PASSWORD=•• \
cert-gen export p12 --ca hd-root-ca -o hd-root-ca.pfx

암호화는 PBES2 / PBKDF2 / AES-256-CBC (Modern2023 프로파일). openssl pkcs12 -info
로 키 백(Shrouded Keybag)과 인증서 백이 모두 들어 있음을 확인할 수 있다.
키스토어 비밀번호는 16자 이상을 권장한다(PKCS#12 KDF 반복이 2048회라 짧은 암호는
보호가 약하다).openssl rand -hex 16을 쓰면 된다.
Java 애플리케이션(구형 Tomcat 등)이 JKS 를 요구할 때 쓴다. keytool 없이 변환한다.
CERT_GEN_EXPORT_PASSWORD=•• cert-gen export jks 1 --alias web -o web.jks
keytool -list -keystore web.jks # (선택) 내용 확인

JKS 는 레거시다. JDK 9+ 의 기본 키스토어는 PKCS#12 이고 Java 8u60+ 도 PKCS#12 를 직접
읽는다. 가능하면export p12로 만든keystore.p12를 쓰자. 발급 번들에도 포함돼 있다.
cert-gen tui 로 같은 작업을 메뉴로 수행한다. 비TTY·TERM=dumb·NO_COLOR 환경에서는
진입을 거부하고 등가 CLI 명령을 안내한다(CLI 가 정본).
| 화면 | 설명 |
|---|---|
| 발급 이력 | 시작 화면. 만료 임박·상태·CA 별 필터 |
| 개인키 관리 | 키 생성·삭제, 보호 열(암호/평문/암호+평문), b 로 평문 동반본 생성 |
| 인증서 발급 | DN·SAN·프로필·키 선택 → 요약 → 결과 |
| CA 신뢰 등록 | Rocky/Debian/Windows/Java 별 신뢰 등록 절차 |




개인키 관리 화면에서 암호화된 서버/클라이언트 키를 고르고
b를 누르면 패스프레이즈
모달이 뜨고, 확인하면 평문 동반본이 생긴다. CA 가 쓰는 키에는b가 거부된다.
발급 번들(zip)에는 바로 쓸 수 있는 파일이 들어 있다.
| 파일 | 용도 |
|---|---|
fullchain.pem + privkey.pem |
nginx / Nginx Proxy Manager 에 바로 등록 |
ca.crt |
클라이언트·서버의 신뢰 저장소에 등록(자가서명 체인은 필수) |
keystore.p12 |
Java / Windows |
cert.pem / chain.pem |
개별 구성 요소 |
# 번들 다시 꺼내기
cert-gen cert bundle <ID> -o ./out
# K8s tls Secret 생성
cert-gen export k8s <ID> --secret-name web-tls --namespace web --with-ca
자가서명 CA 는 각 클라이언트가 ca.crt 를 신뢰 등록해야 동작한다. 플랫폼별 절차는
cert-gen trust show <slug> 또는 TUI 의 CA 신뢰 등록 화면을 참고한다.
privkey.pem 은 평문이다. **상태 디렉터리 접근 통제(0750)**가backup create)은 CA 개인키를 포함한다(0600). 외부로 보낼 때는 별도 암호화.--days / 설정 max_days 로 조정).