인증서 만들기

대문 / 활용 / 인증서 만들기

인증서 만들기

1.1. 개요

인증서 (Cerificate)를 생성하기 위해서 필요한 일련의 과정을 설명합니다.

여기서 설명은 기본적으로 사설 인증서이므로 실제 웹 서버등을 운영하시고자 공인 인증서를 필요로 하는 경우 [https]여기(Let’s Encrypt)[](https://letsencrypt.org/)를 방문해보시는 것을 권해드립니다.

1.2. gnutls의 certtool 을 이용한 인증서 생성

  • Ubuntu 배포판의 경우 "gnutls-bin" 패키지 설치가 필요합니다.
    # 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 <http://gnu.org/licenses/gpl.html>
    
    Please send bug reports to:  <bugs@gnutls.org>
    
  • CA 인증서 생성
    • CA key (CA 비밀키) 생성
      # certtool --generate-privkey --outfile ca-key.pem
      Generating a 3072 bit RSA private key...
      
    • 자체서명 최상위 인증서 (Self-signed CA certificate) 파일 생성
      # certtool --generate-self-signed --load-privkey ca-key.pem --outfile ca.pem
      ... <무수히 많은 질문들을 항목에 맞게 잘 입력하세요> ...
      
  • 서명된 인증서 발급
    • 발급용 key (발급용 인증서의 비밀키) 생성
      # certtool --generate-privkey --outfile key.pem
      Generating a 3072 bit RSA private key...
      
    • CSR (Certificate Signing Request, 인증서 서명 요청) 파일 생성
      # certtool --generate-request --load-privkey key.pem --outfile request.pem
      ... <무수히 많은 질문들을 항목에 맞게 잘 입력하세요> ...
      
    • 서명된 인증서 생성
      # certtool --generate-certificate --load-request request.pem --outfile host.pem --load-ca-certificate ca.pem --load-ca-privkey ca-key.pem
      ... <무수히 많은 질문들을 항목에 맞게 잘 입력하세요> ...
      

1.3. openssl 을 이용한 인증서 생성

  • Ubuntu 배포판의 경우 "openssl" 패키지 설치가 필요합니다.
    # sudo apt install openssl
    ...
    # openssl version
    OpenSSL 1.1.1  11 Sep 2018
    
  • CA 인증서 생성
    • AES256 알고리즘으로 암호화된 CA key (CA 비밀키) 생성
      # 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: <CA key의 암호화 비밀번호 (암호화)>
      Verifying - Enter pass phrase for ca-key.enc.pem: <CA key의 암호화 비밀번호 (암호화)>
      # chmod 0600 "ca-key.enc.pem"
      
      • 기본적으로 이 파일은 엄격히 외부 유출되지 않도록 관리해야 함. (하지만 암호화된 Key 파일이므로 제한적으로 신뢰할수 있는 외부로 제공할 수는 있음.)
      • "<CA key의 암호화 비밀번호 (암호화)>" : CA Key내용을 암호화시에 사용할 암호문을 의미
      • 만약 "<CA key의 암호화 비밀번호 (암호화)>" 을 입력하지 않으려면 "-passout pass:<CA key의 암호화 비밀번호 (암호화)>" 와 같이 실행인자로 주어서 사용할 수 있습니다.
    • 암호화된 CA key를 풀어서 암호화되지 않은 CA key 생성
      # openssl rsa -in "ca-key.enc.pem" -out "ca-key.pem" 
      Enter pass phrase for ca-key.enc.pem: <CA key의 암호화 비밀번호 (복호화)>
      writing RSA key
      # chmod 0600 "ca-key.pem"
      
      • 기본적으로 이 파일은 엄격히 외부 유출되지 않도록 관리해야 함. (절대 유출되어서는 안됨.)
      • "<CA key의 암호화 비밀번호 (복호화)>" : CA Key내용을 암호화시에 사용했던 암호문을 입력하여 복호화를 수행하게 됨.
      • 만약 "<CA key의 암호화 비밀번호 (복호화)>" 을 입력하지 않으려면 "-passin pass:<CA key의 암호화 비밀번호 (복호화)>" 와 같이 실행인자로 주어서 사용할 수 있습니다.
    • 다음과 같이 "ca.conf" (CA 설정파일) 파일을 만들고 하기 내용을 적절히 자신의 항목에 맞도록 수정 후 저장 (본 과정은 선택사항입니다. 하지만 CA 설정파일을 만들고 진행하는 것이 여러가지 오류를 줄일 수 있습니다.)
      [ 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" 파일을 만든 경우
        # openssl req -new -key "ca-key.enc.pem" -out "ca.csr" -config "ca.conf" 
        Enter pass phrase for ca-key.enc.pem: <CA 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]: <ENTER>
        Organization Name (eg, company) [TEST_00_CA_ORG]: <ENTER>
        Organizational Unit Name (eg, section) [TEST_00_CA_CERT_TEAM]: <ENTER>
        Common Name (eg, your name or your servers hostname) [THIS_IS_SSL_CERT_GEN_TEST]: <ENTER>
        
      • "ca.conf" 파일을 만들지 않은 경우
        # openssl req -new -key "ca-key.enc.pem" -out "ca.csr" 
        Enter pass phrase for ca-key.enc.pem: <CA key의 암호화 비밀번호 (복호화)>
        ... <무수히 많은 질문들을 항목에 맞게 잘 입력하세요> ...
        
    • 자체서명 최상위 인증서 (Self-signed CA certificate) 파일 생성
      • "ca.conf" 파일을 만든 경우
        # 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 key의 암호화 비밀번호 (복호화)>
        
      • "ca.conf" 파일을 만들지 않은 경우
        # 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 key의 암호화 비밀번호 (복호화)>
        
    • CA 인증서 정상 이용가능하게 생성되었는지 확인 (아래 내용 중 "SSL server CA : Yes" 문구가 확인되면 OK)
      # 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 (발급용 인증서의 비밀키) 생성
      # 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 생성
      # 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"와는 다른것입니다.)
      [ 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" 파일을 만든 경우
        # 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]: <ENTER>
        Organization Name (eg, company) [TEST_00_CERT_HWPORT]: <ENTER>
        Organizational Unit Name (eg, section) [TEST_00_CERT_HWPORT_TEAM]: <ENTER>
        Common Name (eg, your name or your servers hostname) [THIS_IS_CERT_GEN_TEST_USER_CERT]: <ENTER>
        
      • "host.conf" 파일을 만들지 않은 경우
        # openssl req -new -key "key.enc.pem" -out "host.csr" 
        Enter pass phrase for key.enc.pem: <발급용 key의 암호화 비밀번호 (복호화)>
        ... <무수히 많은 질문들을 항목에 맞게 잘 입력하세요> ...
        
    • 서명된 인증서 생성
      • "host.conf" 파일을 만든 경우
        # 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" 파일을 만들지 않은 경우
        # 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의 암호화 비밀번호 (복호화)>
        
  • 인증서 파일들의 권한 및 소유자 권한 확인 및 부여
    • 나머지 파일들은 추후 재발급 또는 갱신시에 사용하며 삭제해도 무방
      # 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 형식으로 변환
      # openssl x509 -inform PEM -in "<PEM형식 파일명>" -outform DER -out "<DER형식 파일명>" 
      

1.4. 참고자료

Retrieved from https://www.minzkn.com:443/moniwiki/wiki.php/GenerateCertificate
last modified 2023-02-01 12:17:18