OpenSSL!

SSL, TLS

  • SSL(Secure Sockets Layer) 보안 소켓 계층
    • 1990년대 넷스케이프(Netscape)에서 개발한 보안 프로토콜
    • SSL 2.0(1995), SSL 3.0(1996)으로 발전.
  • TLS(Transport Layer Security) 전송 계층 보안
    • SSL 3.0을 기반으로 IETF에서 표준화한 프로토콜.
    • TLS 1.3(2018, 최신 버전)

핸드쉐이크를 통해 세션키(대칭키)를 공유하고 세션키로 암호화 통신 하기 위한 방법이다.
해당 키 교환을 위한 핸드쉐이크를 PKI 기반으로 수행한다.

TLS 1.3 은 여러 키(클라이언트→서버, 서버→클라이언트)를 생성한다.

X.509

ITU-T(국제전기통신연합) 에서 정의한 공개 키 기반 구조(PKI, Public Key Infrastructure) 인증서 구조 표준.
Openssl 로 생성하는 인증서(공개키) 는 모두 대부분 X.509 표준을 따른다.

아래와 같은 구조로 정의되며 ASN.1(Abstract Syntax Notation One) 구조라한다.

Certificate ::= SEQUENCE {
    tbsCertificate       TBSCertificate,
    signatureAlgorithm   AlgorithmIdentifier,
    signatureValue       BIT STRING
}

TBSCertificate ::= SEQUENCE {
    version         [0]  INTEGER,              -- v1(0), v2(1), v3(2)
    serialNumber         INTEGER,              -- 인증서 일련번호
    signature            AlgorithmIdentifier,  -- 서명 알고리즘 (예: SHA256withRSA)
    issuer              Name,                  -- 발급자 정보 (CA의 DN)
    validity            Validity,              -- 유효 기간 (notBefore, notAfter)
    subject             Name,                  -- 소유자 정보 (DN)
    subjectPublicKeyInfo SubjectPublicKeyInfo, -- 공개 키와 알고리즘
    issuerUniqueID  [1]  IMPLICIT BIT STRING OPTIONAL, -- 발급자 고유 ID (선택)
    subjectUniqueID [2]  IMPLICIT BIT STRING OPTIONAL, -- 소유자 고유 ID (선택)
    extensions      [3]  Extensions OPTIONAL  -- 확장 필드 (v3에서 사용)
}

DN은 아래와 같은 정보가 포함된다.

  • Country Name (C): US
  • State or Province Name (ST): California
  • Locality Name (L): San Francisco
  • Organization Name (O): Example Inc.
  • Organizational Unit Name (OU): IT Department
  • Common Name (CN): www.example.com
  • Email Address: admin@example.com

X.509 는 CA 기반에서 동작하는 SSL/TLS 표준이다.
이외에도 이메일, Linux 패키지 서명할 때 사용하는 OpenPGP 같은 인증서 표준이 있다.

CA 인증서(Certificate Authority Certificate)

테스트용으로 인증 기관에서 사용하는것 처럼 사설 루트 인증서 를 생성,

  • ca.key: 루트 개인키
  • ca.crt: 루트 공개키(루트 인증서)

공인 루트 인증서(이하 CA)를 관리하는 공인 인증 기관(CA: Public Certificate Authority) 목록은 아래와 같고,
ca.key 는 물리적 금고에서 보관중이라고 함.

  • DigiCert
  • GlobalSign
  • AWS Certificate Manager
  • Microsoft CA
openssl genrsa -out root_ca.key 2048
openssl req -x509 -new -key root_ca.key -days 3650 -out root_ca.crt \
  -subj "/C=KR/ST=Gyeonggi-do/L=Seongnam-si/\
O=Demo-Comp/OU=Demo-Service/\
CN=RootCA/emailAddress=kouzie@test.com"

서버 개인키, 서버 서명 요청서 생성.

Intermediate CA

보통 인증서는 루트 CA 가 바로 인증해주기 보단 2 단계정도를 레벨로 구성한다.
이때 중간에 있는 CA 기관들을 Intermediate CA 라 부른다.

Intermediate CA 역시 사설로 생성

  • intermediate_ca.key: 중간 CA 개인키
  • intermediate_ca.csr: 서명 요청서(Certificate Signing Request)
    • 중간 CA 의 공개키와 메타데이터를 서명한 파일.
    • 서명을 RootCA 에 제출, RootCA 가 서명한 중간 CA 공개키를 받기 위해 사용함.
  • intermediate_ca.crt: 중간 CA 공개키(중간 CA 인증서)
openssl genrsa -out intermediate_ca.key 2048
openssl req -new -key intermediate_ca.key \
  -out intermediate_ca.csr \
  -subj "/C=KR/ST=Gyeonggi-do/L=Seongnam-si/\
O=Demo-Comp/OU=Demo-Service/\
CN=IntermediateCA/emailAddress=kouzie@test.com"

intermediate_ca.csr 파일을 기반으로 서버 공개키(서버 인증서)를 CA 로 서명 및 생성

openssl x509 -req -in intermediate_ca.csr \
  -CA root_ca.crt \
  -CAkey root_ca.key \
  -CAcreateserial \
  -days 1825 \
  -out intermediate_ca.crt \
  -extensions v3_ca \
  -extfile <(cat <<EOF
[v3_ca]
basicConstraints = critical,CA:TRUE
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
EOF
)
  • -days 1825 RootCA 보단 유효기간을 짧게 설정해야함.
  • -CA root_ca.crt RootCA 공개키로 발급자 정보를 포함, 인증서에 RootCA 정보를 추가(체이닝)
  • -CAkey root_ca.key RootCA 개인키로 csr 파일에 서명
  • -CAcreateserial
    인증서의 고유식별자를 생성, ca.srl 파일에 저장.
  • extensions v3_ca 확장자 섹션 이름. 중간 CA로 동작하도록 설정. extfile <(cat <<EOF ... EOF) 사용하여 확장자 정의를 인라인으로 제공
[v3_ca]
# 인증서가 CA로 동작 가능(인증서 발급 권한 부여).
basicConstraints = critical,CA:TRUE
# digitalSignature: 디지털 서명 가능.
# cRLSign: CRL(인증서 폐지 목록) 서명 가능.
# keyCertSign: 다른 인증서 서명 가능.
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
# 인증서의 공개키에서 고유 식별자 생성.
subjectKeyIdentifier = hash
# 루트 CA의 키 식별자와 정보 포함, 신뢰 체인 추적에 사용.
authorityKeyIdentifier = keyid:always,issuer

명령을 수행하면 root_ca.srl(인증서 고유식별자 파일) 이 생성된다.
향후 Intermediate CA 의 폐기 필요시 인증서 폐기 리스트(Certificate Revocation List) 에 저장될 용도로 사용한다.

Server 인증서

Intermediate CA 를 통해 서버 인증서를 생성,

  • server.key: 서버 개인키
  • server.csr: 서버 서명 요청서(Certificate Signing Request)
    • 서버 공개키와 메타데이터를 서명한 파일.
    • 서명을 IntermediateCA 에 제출, IntermediateCA 가 서명한 서버 공개키를 받기 위해 사용함.
  • server.crt: 서버 공개키(서버 인증서)
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr \
  -subj "/C=KR/ST=Gyeonggi-do/L=Seongnam-si/\
O=Demo-Comp/OU=Demo-Service/\
CN=ServerCN/emailAddress=kouzie@test.com"

server.csr 파일을 기반으로 서버 공개키(서버 인증서)를 IntermediateCA 로 서명 및 생성

openssl x509 -req -in server.csr \
  -CA intermediate_ca.crt \
  -CAkey intermediate_ca.key \
  -CAcreateserial \
  -days 365 -out server.crt

명령을 수행하면 intermediate_ca.srl(인증서 고유식별자 파일) 이 생성된다.
향후 서버 인증서의 폐기 필요시 인증서 폐기 리스트(Certificate Revocation List) 에 저장될 용도로 사용한다.

그러면 RootCA, IntermediateCA 로 구성된 fullchain 서버 인증서가 제작된다.

인증서 파일 포맷 종류

-----BEGIN CERTIFICATE-----
MIIEDjCCAvagAwIBAgIUAMXlft1kCF7moTjpZsTFQi90OBgwDQYJKoZIhvcNAQEL
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE REQUEST-----
MIIC3TCCAcUCAQAwgZcxCzAJBgNVBAYTAktSMRQwEgYDVQQIDAtHeWVvbmdnaS1k
...
-----END CERTIFICATE REQUEST-----
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDUKO4G4+2QfGjP
...
-----END PRIVATE KEY-----

인증서 파일을 만들다 보면 위와같은 포멧, .crt, .pem 같은 확장자 암호 관련 파일이 생성된다.

  • crt(Certificate)
    • X.509 포멧 인증서 파일,
    • PEM 또는 DER 형식으로 인코딩됨.
    • 파일을 열었는데 깨진 문자열 혹은 이진 구조일 경우 DER, 16진수 형태일경우 PEM.
  • pem (Privacy Enhanced Mail)
    • 인증서/키 같은 보안 객체를 Base64로 인코딩하여 저장한 파일.
    • 대부분 crt 파일이 pem 형태로 인코딩되어있음.
  • cer
    • crt 파일과 동일한 역할을 한다.
    • Windows 기반 인증서 파일임을 구분하기 위해서 사용되는 확장자, crt 는 주로 유닉스/리눅스에서 사용.
  • .p12/.pfx
    • 인증서, 개인 키, CA 체인을 하나의 암호화된 파일에 저장하는 형식.
    • PKCS#12 포멧으로 바이너리 형식으로 저장.
    • 백업 또는 이동용으로 주로 사용.

공개 키 암호 표준(Public-Key Cryptography Standard, PKCS)

PKCS#1, PKCS#8, PKCS#10, PKCS#12 포멧은 PKI 에서 매우 자주 사용됨.

.key 확장자의 경우 PKCS#1 혹은 PKCS#8 .p12 확장자의 경우 PKCS#12

  • PKCS#1
    • RSA 개인키를 저장하는 가장 기본적인 형식
    • -----BEGIN RSA PRIVATE KEY----- 로 시작함
    • 아래 정보가 저장됨
version           INTEGER,  -- 0
modulus           INTEGER,  -- n
publicExponent    INTEGER,  -- e
privateExponent   INTEGER,  -- d
prime1            INTEGER,  -- p
prime2            INTEGER,  -- q
exponent1         INTEGER,  -- d mod (p-1)
exponent2         INTEGER,  -- d mod (q-1)
coefficient       INTEGER   -- (q^-1) mod p
  • PKCS#8
    • 개인 키를 저장하는 일반화된 표준, RSA뿐만 아니라 EC, DSA 등 다양한 알고리즘을 지원
    • PKCS#8 가 더 최신 포멧
    • -----BEGIN PRIVATE KEY----- 로 시작함
    • 아래 정보가 저장됨
version         INTEGER,              -- 0
algorithm       AlgorithmIdentifier,  -- 예: rsaEncryption
privateKey      OCTET STRING          -- PKCS#1 RSAPrivateKey 또는 다른 키 데이터
  • PKCS#10
    • 인증서 서명 요청 표준
    • -----BEGIN CERTIFICATE REQUEST----- 로 시작함
  • PKCS#12
    • 개인 정보 교환 구문 표준
    • 인증서, 개인 키, CA 체인을 하나의 암호화된 파일에 저장.
    • 바이너리 포멧

카테고리:

업데이트: