#keywords 활용,인증서,발급,서명,sign,cetificate,generate,openssl,x509,rsa,dhe,encrypt,decrypt,public,private,key,비밀키,공개키,letsencrypt,crl,expire #title 인증서 만들기 [wiki:Home 대문] / [wiki:CategoryHowTo 활용] / [wiki:GenerateCertificate 인증서 만들기] ---- == [wiki:GenerateCertificate 인증서 만들기] == * 작성자 조재혁([mailto:minzkn@minzkn.com]) * 고친과정 2018년 4월 4일 : 처음씀[[br]] 2020년 2월 28일 : Ubuntu 18.04.4 LTS 기준환경에서 설치된 패키지 기준으로 다시 정리[[br]] [[TableOfContents]] === 개요 === 인증서 (Cerificate)를 생성하기 위해서 필요한 일련의 과정을 설명합니다. 여기서 설명은 기본적으로 사설 인증서이므로 실제 웹 서버등을 운영하시고자 공인 인증서를 필요로 하는 경우 [^https://letsencrypt.org/ 여기(Let’s Encrypt)]를 방문해보시는 것을 권해드립니다. === gnutls의 certtool 을 이용한 인증서 생성 === * Ubuntu 배포판의 경우 "gnutls-bin" 패키지 설치가 필요합니다. {{{#!plain # sudo apt install gnutls-bin ... # certtool -v certtool 3.5.18 Copyright (C) 2000-2018 Free Software Foundation, and others, all rights reserved. This is free software. It is licensed for use, modification and redistribution under the terms of the GNU General Public License, version 3 or later Please send bug reports to: }}} * CA 인증서 생성 * CA key (CA 비밀키) 생성 {{{#!plain # certtool --generate-privkey --outfile ca-key.pem Generating a 3072 bit RSA private key... }}} * 자체서명 최상위 인증서 (Self-signed CA certificate) 파일 생성 {{{#!plain # certtool --generate-self-signed --load-privkey ca-key.pem --outfile ca.pem ... <무수히 많은 질문들을 항목에 맞게 잘 입력하세요> ... }}} * 서명된 인증서 발급 * 발급용 key (발급용 인증서의 비밀키) 생성 {{{#!plain # certtool --generate-privkey --outfile key.pem Generating a 3072 bit RSA private key... }}} * CSR (Certificate Signing Request, 인증서 서명 요청) 파일 생성 {{{#!plain # certtool --generate-request --load-privkey key.pem --outfile request.pem ... <무수히 많은 질문들을 항목에 맞게 잘 입력하세요> ... }}} * 서명된 인증서 생성 {{{#!plain # certtool --generate-certificate --load-request request.pem --outfile host.pem --load-ca-certificate ca.pem --load-ca-privkey ca-key.pem ... <무수히 많은 질문들을 항목에 맞게 잘 입력하세요> ... }}} === openssl 을 이용한 인증서 생성 === * Ubuntu 배포판의 경우 "openssl" 패키지 설치가 필요합니다. {{{#!plain # sudo apt install openssl ... # openssl version OpenSSL 1.1.1 11 Sep 2018 }}} * CA 인증서 생성 * AES256 알고리즘으로 암호화된 CA key (CA 비밀키) 생성 {{{#!plain # openssl genrsa -aes256 -out "ca-key.enc.pem" Generating RSA private key, 2048 bit long modulus (2 primes) .....................................................+++++ ...................................................................+++++ e is 65537 (0x010001) Enter pass phrase for ca-key.enc.pem: Verifying - Enter pass phrase for ca-key.enc.pem: # chmod 0600 "ca-key.enc.pem" }}} * 기본적으로 이 파일은 엄격히 외부 유출되지 않도록 관리해야 함. (하지만 암호화된 Key 파일이므로 제한적으로 신뢰할수 있는 외부로 제공할 수는 있음.) * "" : CA Key내용을 암호화시에 사용할 암호문을 의미 * 만약 "" 을 입력하지 않으려면 "-passout pass:" 와 같이 실행인자로 주어서 사용할 수 있습니다. * 암호화된 CA key를 풀어서 암호화되지 않은 CA key 생성 {{{#!plain # openssl rsa -in "ca-key.enc.pem" -out "ca-key.pem" Enter pass phrase for ca-key.enc.pem: writing RSA key # chmod 0600 "ca-key.pem" }}} * 기본적으로 이 파일은 엄격히 외부 유출되지 않도록 관리해야 함. (절대 유출되어서는 안됨.) * "" : CA Key내용을 암호화시에 사용했던 암호문을 입력하여 복호화를 수행하게 됨. * 만약 "" 을 입력하지 않으려면 "-passin pass:" 와 같이 실행인자로 주어서 사용할 수 있습니다. * 다음과 같이 "ca.conf" (CA 설정파일) 파일을 만들고 하기 내용을 적절히 자신의 항목에 맞도록 수정 후 저장 (본 과정은 선택사항입니다. 하지만 CA 설정파일을 만들고 진행하는 것이 여러가지 오류를 줄일 수 있습니다.) {{{#!plain [ req ] default_bits = 2048 default_md = sha1 default_keyfile = rootca.key distinguished_name = req_distinguished_name extensions = v3_ca req_extensions = v3_ca [ v3_ca ] basicConstraints = critical, CA:TRUE, pathlen:0 subjectKeyIdentifier = hash ##authorityKeyIdentifier = keyid:always, issuer:always keyUsage = keyCertSign, cRLSign nsCertType = sslCA, emailCA, objCA [req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = KR countryName_min = 2 countryName_max = 2 # 회사명 입력 organizationName = Organization Name (eg, company) organizationName_default = TEST_00_CA_ORG # 부서 입력 organizationalUnitName = Organizational Unit Name (eg, section) organizationalUnitName_default = TEST_00_CA_CERT_TEAM # SSL 서비스할 domain 명 입력 commonName = Common Name (eg, your name or your server's hostname) commonName_default = THIS_IS_SSL_CERT_GEN_TEST commonName_max = 64 }}} * CSR (Certificate Signing Request, 인증서 서명 요청) 파일 생성 * "ca.conf" 파일을 만든 경우 {{{#!plain # openssl req -new -key "ca-key.enc.pem" -out "ca.csr" -config "ca.conf" Enter pass phrase for ca-key.enc.pem: You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [KR]: Organization Name (eg, company) [TEST_00_CA_ORG]: Organizational Unit Name (eg, section) [TEST_00_CA_CERT_TEAM]: Common Name (eg, your name or your servers hostname) [THIS_IS_SSL_CERT_GEN_TEST]: }}} * "ca.conf" 파일을 만들지 않은 경우 {{{#!plain # openssl req -new -key "ca-key.enc.pem" -out "ca.csr" Enter pass phrase for ca-key.enc.pem: ... <무수히 많은 질문들을 항목에 맞게 잘 입력하세요> ... }}} * 자체서명 최상위 인증서 (Self-signed CA certificate) 파일 생성 * "ca.conf" 파일을 만든 경우 {{{#!plain # openssl x509 -req -days "<일단위 유효시간>" -extensions v3_ca -set_serial 1 -in "ca.csr" -signkey "ca-key.enc.pem" -outform PEM -out "ca.pem" -extfile "ca.conf" Signature ok subject=C = KR, O = TEST_00_CA_ORG, OU = TEST_00_CA_CERT_TEAM, CN = THIS_IS_SSL_CERT_GEN_TEST Getting Private key Enter pass phrase for ca-key.enc.pem: }}} * "ca.conf" 파일을 만들지 않은 경우 {{{#!plain # openssl x509 -req -days "<일단위 유효시간>" -extensions v3_ca -set_serial 1 -in "ca.csr" -signkey "ca-key.enc.pem" -outform PEM -out "ca.pem" Signature ok subject=C = KR, O = TEST_00_CA_ORG, OU = TEST_00_CA_CERT_TEAM, CN = THIS_IS_SSL_CERT_GEN_TEST Getting Private key Enter pass phrase for ca-key.enc.pem: }}} * CA 인증서 정상 이용가능하게 생성되었는지 확인 (아래 내용 중 "SSL server CA : Yes" 문구가 확인되면 OK) {{{#!plain # openssl x509 -inform PEM -text -noout -in ca.pem -purpose Certificate: Data: Version: 3 (0x2) Serial Number: 1 (0x1) Signature Algorithm: sha256WithRSAEncryption Issuer: C = KR, O = TEST_00_CA_ORG, OU = TEST_00_CA_CERT_TEAM, CN = THIS_IS_SSL_CERT_GEN_TEST Validity Not Before: Feb 28 04:32:06 2020 GMT Not After : Feb 25 04:32:06 2030 GMT Subject: C = KR, O = TEST_00_CA_ORG, OU = TEST_00_CA_CERT_TEAM, CN = THIS_IS_SSL_CERT_GEN_TEST Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (2048 bit) Modulus: 00:d6:21:3d:90:90:07:32:8e:e5:54:f1:76:25:92: d3:3a:bf:f7:1b:40:bf:e8:73:37:bf:0b:40:22:f4: 1e:af:5b:fe:06:9b:03:54:e1:20:56:3d:5e:e1:b1: 1b:a0:ff:d0:4d:bb:15:6c:b3:c3:04:1e:5e:38:81: 48:a3:46:67:1c:60:d9:43:9d:8c:00:98:06:cf:c1: b4:b6:49:7c:45:a4:95:a9:e8:57:ee:98:ba:4b:96: 89:58:ac:c9:cb:03:db:af:ae:9a:21:33:25:23:91: dc:53:2c:2e:f0:ba:34:f4:d2:00:dd:5e:d7:a0:4f: 3e:dc:25:f2:bb:70:be:d7:24:58:24:d4:97:10:1c: 21:0e:b1:92:d3:8c:56:1d:be:17:62:5b:25:83:16: e4:5f:f4:83:80:46:31:7f:6d:d2:cf:91:71:76:ec: d4:c2:87:fb:82:d9:86:14:67:bd:ad:75:ef:b1:79: 17:f9:b9:12:a6:dc:fe:6c:09:b2:39:b7:ae:8d:7d: b2:b4:b4:72:22:50:04:2c:5a:01:99:03:65:68:73: 51:56:e8:90:98:c9:bd:78:f2:77:cc:99:bf:5f:6b: b9:f7:a6:ee:8e:49:fa:f0:f7:59:e6:4d:2e:44:73: 70:f0:ff:ef:4a:18:46:8a:53:e2:22:b3:09:7d:ab: 50:91 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:TRUE, pathlen:0 X509v3 Subject Key Identifier: 7A:5D:1E:A6:DB:68:71:B8:57:61:63:3E:B7:B5:AA:7E:CD:F8:DB:A9 X509v3 Key Usage: Certificate Sign, CRL Sign Netscape Cert Type: SSL CA, S/MIME CA, Object Signing CA Signature Algorithm: sha256WithRSAEncryption 45:b4:c2:f5:cf:24:b6:6d:30:48:c9:34:af:7c:5f:1c:3a:ce: e9:a4:53:f1:5e:2b:70:1e:23:f0:5b:fb:2c:48:9c:8c:b2:b8: 9e:c7:f8:2e:e7:0f:97:43:0e:60:27:fc:02:60:14:c5:c0:dc: 29:e6:ad:34:7c:c4:5e:40:00:58:8b:2e:a3:cb:1f:18:b9:ce: 24:42:66:ee:cf:16:92:83:91:ad:3c:b5:95:29:10:b8:34:c3: 40:67:eb:3d:43:c5:94:86:04:10:30:3a:b9:54:a0:80:f8:88: 13:95:db:eb:df:a0:c6:62:c0:ee:bf:71:36:1a:13:f7:b8:8d: d4:6b:ba:41:82:fd:2f:1c:5a:e5:4a:30:73:07:24:98:1e:4b: 69:82:ec:25:97:d4:84:d2:6e:4d:c0:eb:19:38:27:e9:46:50: 54:84:99:7c:1a:eb:25:bb:db:7f:de:f5:b5:f8:63:32:f9:7c: f1:df:92:c8:4a:4a:93:3c:7a:a0:91:62:ac:47:ea:95:3e:12: f9:3a:85:f6:1a:df:c5:6f:f0:d8:db:98:0b:66:52:94:96:41: 0d:99:b2:27:69:9d:cd:26:02:a5:7d:d9:f9:0d:3b:f2:7b:3f: cc:9b:3a:af:1c:54:4b:b7:58:0d:e3:48:d8:9b:65:52:24:ac: 63:68:62:b4 Certificate purposes: SSL client : No SSL client CA : Yes SSL server : No SSL server CA : Yes Netscape SSL server : No Netscape SSL server CA : Yes S/MIME signing : No S/MIME signing CA : Yes S/MIME encryption : No S/MIME encryption CA : Yes CRL signing : Yes CRL signing CA : Yes Any Purpose : Yes Any Purpose CA : Yes OCSP helper : Yes OCSP helper CA : Yes Time Stamp signing : No Time Stamp signing CA : Yes }}} * 서명된 인증서 발급 * AES256 알고리즘으로 암호화된 발급용 key (발급용 인증서의 비밀키) 생성 {{{#!plain # openssl genrsa -aes256 -out "key.enc.pem" Generating RSA private key, 2048 bit long modulus (2 primes) ..............................+++++ ....+++++ e is 65537 (0x010001) Enter pass phrase for key.enc.pem: <발급용 key의 암호화 비밀번호 (암호화)> Verifying - Enter pass phrase for key.enc.pem: <발급용 key의 암호화 비밀번호 (암호화)> # chmod 0600 "key.enc.pem" }}} * 기본적으로 이 파일은 엄격히 외부 유출되지 않도록 관리해야 함. (하지만 암호화된 Key 파일이므로 제한적으로 신뢰할수 있는 외부로 제공할 수는 있음.) * "<발급용 key의 암호화 비밀번호 (암호화)>" : 발급용 Key내용을 암호화시에 사용할 암호문을 의미 * 만약 "<발급용 key의 암호화 비밀번호 (암호화)>" 을 입력하지 않으려면 "-passout pass:<발급용 key의 암호화 비밀번호 (암호화)>" 와 같이 실행인자로 주어서 사용할 수 있습니다. * 암호화된 발급용 key를 풀어서 암호화되지 않은 발급용 key 생성 {{{#!plain # openssl rsa -in "key.enc.pem" -out "key.pem" Enter pass phrase for key.enc.pem: <발급용 key의 암호화 비밀번호 (복호화)> writing RSA key # chmod 0600 "key.pem" }}} * 기본적으로 이 파일은 엄격히 외부 유출되지 않도록 관리해야 함. (절대 유출되어서는 안됨.) * "<발급용 key의 암호화 비밀번호 (복호화)>" : 발급용 Key내용을 암호화시에 사용했던 암호문을 입력하여 복호화를 수행하게 됨. * 만약 "<발급용 key의 암호화 비밀번호 (복호화)>" 을 입력하지 않으려면 "-passin pass:<발급용 key의 암호화 비밀번호 (복호화)>" 와 같이 실행인자로 주어서 사용할 수 있습니다. * 다음과 같이 "host.conf" (발급용 설정파일) 파일을 만들고 하기 내용을 적절히 자신의 항목에 맞도록 수정 후 저장 (본 과정은 선택사항입니다. 하지만 발급용 설정파일을 만들고 진행하는 것이 여러가지 오류를 줄일 수 있습니다. 이것은 위의 "ca.conf"와는 다른것입니다.) {{{#!plain [ req ] default_bits = 2048 default_md = sha1 default_keyfile = rootca.key distinguished_name = req_distinguished_name extensions = v3_user ## 인증서 요청시에도 extension 이 들어가면 authorityKeyIdentifier 를 찾지 못해 에러가 나므로 막아둔다. ## req_extensions = v3_user [ v3_user ] # Extensions to add to a certificate request basicConstraints = CA:FALSE authorityKeyIdentifier = keyid,issuer subjectKeyIdentifier = hash keyUsage = nonRepudiation, digitalSignature, keyEncipherment ## SSL 용 확장키 필드 extendedKeyUsage = serverAuth,clientAuth subjectAltName = @alt_names [ alt_names] ## Subject AltName의 DNSName field에 SSL Host 의 도메인 이름을 적어준다. ## 멀티 도메인일 경우 *.minzkn.com 처럼 쓸 수 있다. DNS.1 = test01-www.minzkn.com DNS.2 = minzkn.com DNS.3 = *.minzkn.com [req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = KR countryName_min = 2 countryName_max = 2 # 회사명 입력 organizationName = Organization Name (eg, company) organizationName_default = TEST_00_CERT_HWPORT # 부서 입력 organizationalUnitName = Organizational Unit Name (eg, section) organizationalUnitName_default = TEST_00_CERT_HWPORT_TEAM # SSL 서비스할 domain 명 입력 commonName = Common Name (eg, your name or your server's hostname) commonName_default = THIS_IS_CERT_GEN_TEST_USER_CERT commonName_max = 64 }}} * CSR (Certificate Signing Request, 인증서 서명 요청) 파일 생성 * "host.conf" 파일을 만든 경우 {{{#!plain # openssl req -new -key "key.enc.pem" -out "host.csr" -config "host.conf" Enter pass phrase for key.enc.pem: <발급용 key의 암호화 비밀번호 (복호화)> You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [KR]: Organization Name (eg, company) [TEST_00_CERT_HWPORT]: Organizational Unit Name (eg, section) [TEST_00_CERT_HWPORT_TEAM]: Common Name (eg, your name or your servers hostname) [THIS_IS_CERT_GEN_TEST_USER_CERT]: }}} * "host.conf" 파일을 만들지 않은 경우 {{{#!plain # openssl req -new -key "key.enc.pem" -out "host.csr" Enter pass phrase for key.enc.pem: <발급용 key의 암호화 비밀번호 (복호화)> ... <무수히 많은 질문들을 항목에 맞게 잘 입력하세요> ... }}} * 서명된 인증서 생성 * "host.conf" 파일을 만든 경우 {{{#!plain # openssl x509 -req -days "<일단위 유효시간>" -extensions v3_user -in "host.csr" -CA "ca.pem" -CAcreateserial -CAkey "ca-key.enc.pem" -outform PEM -out "host.pem" -extfile "host.conf" Signature ok subject=C = KR, O = TEST_00_CERT_HWPORT, OU = TEST_00_CERT_HWPORT_TEAM, CN = THIS_IS_CERT_GEN_TEST_USER_CERT Getting CA Private Key Enter pass phrase for ca-key.enc.pem: <발급용 key의 암호화 비밀번호 (복호화)> }}} * "host.conf" 파일을 만들지 않은 경우 {{{#!plain # openssl x509 -req -days "<일단위 유효시간>" -extensions v3_user -in "host.csr" -CA "ca.pem" -CAcreateserial -CAkey "ca-key.enc.pem" -outform PEM -out "host.pem" Signature ok subject=C = KR, O = TEST_00_CERT_HWPORT, OU = TEST_00_CERT_HWPORT_TEAM, CN = THIS_IS_CERT_GEN_TEST_USER_CERT Getting CA Private Key Enter pass phrase for ca-key.enc.pem: <발급용 key의 암호화 비밀번호 (복호화)> }}} * 인증서 파일들의 권한 및 소유자 권한 확인 및 부여 * 나머지 파일들은 추후 재발급 또는 갱신시에 사용하며 삭제해도 무방 {{{#!plain # ls -al -rw-r--r-- 1 root root 1295 Feb 27 04:34 ca.conf => 재발급시 사용 -rw-r--r-- 1 root root 1180 Feb 27 04:43 ca.csr => 재발급시 사용 -rw------- 1 root root 1766 Feb 27 04:18 ca-key.enc.pem => (필수 파일) 0644 또는 0400 -rw------- 1 root root 1675 Feb 27 04:21 ca-key.pem => (필수 파일) 0644 또는 0400 -rw-r--r-- 1 root root 1273 Feb 27 04:44 ca.pem => (필수 파일) 0644 -rw-r--r-- 1 root root 41 Feb 27 05:30 ca.srl => 삭제해도 무방 -rw-r--r-- 1 root root 1758 Feb 27 05:09 host.conf => 재발급시 사용 -rw-r--r-- 1 root root 1045 Feb 27 05:29 host.csr => 재발급시 사용 -rw-r--r-- 1 root root 1298 Feb 27 05:30 host.pem => (필수 파일) 0644 -rw------- 1 root root 1766 Feb 27 05:12 key.enc.pem => (필수 파일) 0644 또는 0400 -rw------- 1 root root 1675 Feb 27 05:13 key.pem => (필수 파일) 0644 또는 0400 => 파일명에 "key" 문구가 있는 파일들은 모두 외부 유출에 민감한 비밀키를 가진 파일입니다. => "*.conf" 파일들은 추후 재발급시 유용한 설정파일입니다. => "*.csr" 파일은 "*.conf" 또는 발급내용이 변경되지 않는 경우 단순 유효시간만 연장하는 등의 발급을 위해 재사용할 수 있습니다. => "*.srl" 파일은 serial 정보를 담고 있으며 삭제해도 무방한 부수적으로 생성된 임시파일입니다. => "*.pem" 파일은 형식이 PEM 형식인 파일들도 cat 명령으로 파일 내용을 확인시 ASCII 로 구성된 형태의 내용을 가지고 있습니다. => "*.der" 파일은 형식이 DER 형식인 binary 형식의 인증서 파일입니다. => "*.crt" 파일은 통상적(대부분)으로 "*.pem" 또는 "*.der" 형식등의 파일을 이름만 바꾼 인증서 파일입니다. }}} * 인증서의 포맷 변환 (다른 인증서 형식을 요구하는 특별한 경우) * PEM 형식을 DER 형식으로 변환 {{{#!plain # openssl x509 -inform PEM -in "" -outform DER -out "" }}} === 참고자료 === * [^https://letsencrypt.org/ Let’s Encrypt] (무료로 공인 인증서를 발급 가능) * Ubuntu 배포판 사용자의 경우 다음과 같이 발급 및 갱신을 관리하는 도구를 설치 가능 {{{#!plain # sudo apt install letsencrypt 또는 # sudo apt install certbot }}} * [^https://github.com/minzkn/cert 인증서 생성 예제 스크립트 (example_generate_cert_script source)] * [wiki:HowTo_tls_ssl_pcap_analysis TLS(SSL) 연결이 어떤 알고리즘으로 선택되어 암복호화가 진행된건지 확인하는 방법] * OpenSSL Cipher Suite Name mapping: https://testssl.sh/openssl-rfc.mapping.html * 간단히 쉘에서 TLS 연결 테스트 하려면 {{{#!plain # openssl s_client -no_ssl2 -no_ssl3 -connect 10.0.15.249:6514 -state -status # openssl s_client -debug -tlsextdebug -no_ssl2 -no_ssl3 -connect 10.0.15.249:6514 -state -status -msg # openssl s_client -debug -tlsextdebug -no_ssl2 -no_ssl3 -connect 10.0.15.249:6514 -state -status -msg -cipher '' }}} * Ciphers list 확인 {{{#!plain # echo "cipher-suite(\"$(openssl ciphers -v | grep TLSv1.2 | awk '{print $1}' | xargs echo -n | sed 's/ /:/g' | sed -e 's/:$//')\")" }}} * [^https://www.lesstif.com/pages/viewpage.action?pageId=7635159 OpenSSL 자주 쓰는 명령어(command) 및 사용법, tip 정리 - 정광섭님이 작성] * [^https://en.wikipedia.org/wiki/Certificate_revocation_list Certificate revocation list (CRL) - wikipedia] * [^https://www.ssl.com/faqs/what-is-a-san-certificate/ What is a SAN(Subject Alternate Name) Certificate?] * [^https://tools.ietf.org/html/rfc5280 Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile] * [^https://www.roe.ch/SSLsplit] * [^https://testssl.sh/openssl-rfc.mapping.html OpenSSL Cipher Suite Name mapping]