0. 용어 정리

PKI (Public Key Infrastructure); 공개키 기반 구조

X.509: 공개키 인증서와 인증 알고리즘을 사용하기 위한 PKI 표준

PKCS (Public Key Cryptography Standards): Private Key를 저장하는 문법에 관한 표준
            PKCS#1, PKCS#8, PKCS#12 등을 사용

CRL (Certificate Revocation List), OCSP (Online Certificate Status Protocol): 인증서 유효성 점검을 위한 표준/방법

CA (Certificate Authority): 인증 기관

ASN.1 (Abstract Syntax Notation One): 추상 구문 기법, 네트웍상의 데이터 교환을 정의한 프로토콜

RSA (Rivest–Shamir–Adleman): 공개키 암호시스템의 하나

ECDSA (Elliptic Curve Digital Signature Algorithm): 타원곡선을 이용한 전자서명 알고리즘


0-2. 인코딩/파일 종류 정리

참고로 당연히 아래에 적는 확장자는 참고용으로 강제사항은 아님.
PEM 포맷의 개인키를 my.key.pem, my.key, key.pem 등등 저장하기 나름.

인코딩에 따른 구분

 종류

 확장자

 설명

 DER (Distinguished Encoding Representation)

 .der

 ASN.1을 표현하는 방식의 종류. (바이너리로 저장됨)

 PEM (Privacy Enhanced Mail)

 .pem

 Base64로 인코딩된 ASCII 텍스트
 (표준으로 더 자주 사용됨)


내용에 따른 구분

 종류

 확장자

 설명

 Private Key

 .key

 개인키

 Certificate

 .cer (Windows 주로 사용)
 .crt (*NIX 주로 사용)

 인증서

 PKCS #12

 .p12, .pfx

 하나의 파일에 개인키, 인증서 등을 같이 저장하는 방식에 대한 표준

 Certificate Signing Request

 .csr

 인증서 발급을 위해 내 개인키 서명을 CA에게 보내기 위한 파일

 Serial .srl

 CA가 인증서를 발급할 때 Serial 을 관리하기 위한 파일



1. OpenSSL 명령어

* 기본 config 경로: /etc/pki/tls/openssl.cnf

1) Private Key 생성

openssl genrsa -out key.pem 2048


[옵션]

-des, -seed, -aes256, ...: 해당하는 방식으로 키 암호화. 미사용시 암호화 X

-passout pass:PASSWORD: 키를 암호화할 경우 암호 지정. 미사용시 입력 프롬프트가 뜸

-f4 (0x10001), -3: E value 지정. 기본값: -f4

1024, 2048, 3072, 4096, ...: Private Key Bit 크기. 아래 부록 참고




2) CSR 생성

openssl req -new -key key.pem -out my.csr


[옵션]

-md5, -sha1, -sha256, ...: 서명에 사용할 Digest. 기본값은 버전마다 다르고 적당히 sha256 사용.
            전체 목록은 openssl dgst -h

-subj: 인증서 주제 설정. 미사용시 입력 프롬프트 표시
    예시) -subj "/C=KR/O=sho/CN=SHO Certificate"

 필드

 의미

 예시

 /C=

 국가

 KR

 /ST=

 State, 한국이라면 시/도

 Seoul

 /L=

 Location

 Yongsan

 /O=

 Organization, 회사명

 회사

 /OU=

 Organization Unit, 부서명

 부서

 /CN=

 Common Name

 SHO Root CA, blog.ioate.kr 등




3) CSR로부터 인증서 생성

X.509 V3 확장 설정

(아래에서 사용할 ca.ext, end.ext 파일)

Web TLS 인증서 (CA용) - ca.ext

basicConstraints = critical, CA:TRUE
#basicConstraints = critical, CA:TRUE, pathlen:0

subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
keyUsage = cRLSign, keyCertSign


Web TLS 인증서 (End-entity, 사이트용) - end.ext

basicConstraints = critical, CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = DNS:blog.iolate.kr, IP:1.1.1.1


CA 인증서 생성

openssl x509 -req -days 3650 -extfile ca.ext -signkey key.pem -in my.csr -out root.crt


[옵션]

-set_serial 1: 시리얼 값 지정. 미지정시 임의값 생성

-md5, -sha1, -sha256, ...: 서명에 사용할 Digest.
            전체 목록은 openssl dgst -h
            직접 신뢰 설정을 하는 Root CA 가 아니라면, sha256 사용. sha1 등 취약한 digest 사용시 브라우저에서 경고함


End-entity 인증서 생성

openssl x509 -req -days 365 -extfile end.ext -CA root.crt -CAcreateserial -CAkey my.key -in my.csr -out end.crt
openssl x509 -req -days 365 -extfile end.ext -CA root.crt -CAserial root.srl -CAkey my.key -in my.csr -out end.crt


[옵션]

-CAcreateserial: 시리얼 자동 지정 및 시리얼 파일 생성 (.srl)

-CAserial root.srl: CAcreateserial 로 한번 발급한 이후에는 이 옵션으로 시리얼 생성 파일 입력

-md5, -sha1, -sha256, ...: 서명에 사용할 Digest. sha256 사용. sha1 등 취약한 digest 사용시 브라우저에서 경고함



4) 생성된 파일 정보 확인

CSR / 인증서 / 개인키

openssl [req/x509/rsa] -noout -text -in [my.csr/end.crt/my.key]
openssl [req/x509/rsa] -noout -modulus -in [my.csr/end.crt/my.key] | openssl md5



2. 부록

Private Key 비트 크기

출처: https://en.wikipedia.org/wiki/Key_size

(대략적 요약)

* 128bit AES가 충분한 보안 수준으로 고려되었지만, 양자 컴퓨터의 등장 후 비밀 문서에 256bit 사용 권고

* 1024bit RSA와 80bit 대칭키 /
   2048bit RSA와 112bit 대칭키 / 
   3072bit RSA와 128bit 대칭키 /
   15360bit RSA와 256bit 대칭키  가 서로 보안 수준이 비슷하다고 판단됨.

* 1024bit RSA는 2006~2010년에 취약해짐.
   2048bit RSA는 2030년까지 유효할 것으로 판단.
   2030년 이후에는 3072bit 사용 권고


3. 참고

Wikipedia, OpenSSL 문서, 등등...

(그때그때 정리해둔 문서를 다시 정리한거라 참고 URL이 없음..ㅠ)

이건 정리용.


1. Root CA 생성

# CA private key 생성
openssl genrsa -out ca.key 2048

# CA request 생성
openssl req -new -key ca.key -out ca.csr -subj "/C=KR/O=TIM Lab/CN=My VPN CA"

# CA 인증서 생성
echo "basicConstraints = critical, CA:TRUE
subjectKeyIdentifier = hash
keyUsage = digitalSignature, keyCertSign, cRLSign" > ca.ext

openssl x509 -req -days 3650 -extfile ca.ext -set_serial 1 -signkey ca.key -in ca.csr -out ca.crt

# 필요없는 설정파일과 csr 제거
rm ca.ext ca.csr


2. ta.key, dh2048.pem 생성 

openssl dhparam -out dh2048.pem 2048
openvpn --genkey --secret ta.key


3. 서버용 인증서 생성

# private key 생성
openssl genrsa -out cert.key 2048

# csr 생성
openssl req -new -key cert.key -out cert.csr -subj "/C=KR/O=My Organization/CN=VPN Server"

# CA 인증서/키로 인증서 생성
echo "basicConstraints = critical, CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth" > cert.ext

openssl x509 -req -days 3650 -extfile cert.ext -CA ca.crt -CAcreateserial -CAkey  ca.key -in cert.csr -out cert.crt

# 필요없는 설정파일과 csr 제거
rm cert.ext cert.csr

# 서버 인증서, 키 등 이동 / 복사
cp ca.crt /etc/openvpn/ca.crt
cp cert.key /etc/openvpn/server.key
cp ta.key /etc/openvpn/ta.key
mv cert.crt /etc/openvpn/server.crt



4. 클라이언트용 인증서 생성

사실 서버 인증서 생성과 큰 차이 없다. X.509 의 설정파일 내용 정도?
# private key 생성
openssl genrsa -out cert.key 2048

CERT_NAME="Gildong Hong"

# csr 생성
openssl req -new -key cert.key -out cert.csr -subj "/C=KR/O=My Organization/CN=$CERT_NAME"

# CA 인증서/키로 인증서 생성
echo "basicConstraints = critical, CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = digitalSignature" > cert.ext

openssl x509 -req -days 3650 -extfile cert.ext -CA ca.crt -CAcreateserial -CAkey  ca.key -in cert.csr -out "clients/$CERT_NAME.crt"

# 필요없는 설정파일과 csr 제거
rm cert.ext cert.csr



5. ovpn 설정파일 만들기

exec 3> VPN.ovpn

echo "client
remote SERVER_HOST PORT

dev tun
proto udp
resolv-retry infinite
nobind
cipher AES-256-CBC
auth SHA256
key-direction 1
persist-key
persist-tun
remote-cert-tls server
verb 3

;redirect-gateway def1 bypass-dhcp
;auth-user-pass
" >&3

printf "\n\n<ca>\n" >&3
cat ca.crt >&3
printf "</ca>\n\n<tls-auth>\n" >&3
cat ta.key >&3
printf "</tls-auth>\n\n<cert>\n" >&3
cat "clients/$CERT_NAME.crt" >&3
printf "</cert>\n\n<key>\n" >&3
cat cert.key >&3
printf "</key>" >&3

exec 3>&-


+ Recent posts