やさしい自己認証局と自己署名証明書の作り方

9月 29, 2020apache,CentOS,EC2,セキュリティ関連

概要

  • 今回はテストのため、開発環境に自己認証局を構築し、自己認証局による自己署名証明書を発行しました。手順をまとめます。
  • 自己署名証明書は、自分を認証局(CA)として立て、自分で自分の正当性を証明するいわゆる「オレオレ証明書」となります。自己署名証明書の利用で、通信は暗号化されますが、組織の実在性確認はできません。あくまでもテスト向けであり、サービス向けには信頼できる第三者認証局が発行した証明書を利用します。
  • AWS では、ACM(AWS Certificate Manager)で証明書を発行する構成が多いですが、Load Balancer ではSSL終端せず、バックエンドのEC2やコンテナでSSL終端もあり得ます。このような構成では、ACMではなく、外部認証局 or 自己認証局で発行した証明書をバックエンド側で配置することもあります。

 

自己認証局と自己署名証明書の作り方

自己認証局の作り方

  • 先ず、自己認証局用の秘密鍵と証明書を作成します。
  • Linuxサーバーにhttpd, mod_sslをインストールします。(下記ログには含まず)
  • openssl genrsaコマンドで、RSA 2048 bit の秘密鍵を作成します。秘密鍵は、/etc/pki/CA/private/niikawa-test-ca.key として配置しています。
  • openssl reqコマンドで上記秘密鍵を使用して、CSRを作成します。-keyで秘密鍵を指定します。証明書の署名アルゴリズムにSHA-256を指定します。CSRは、/etc/pki/CA/niikawa-test-cacert.csr として配置しています。
  • openssl x509コマンドで、CA証明書を発行します。-inでCSRを指定します。CAの秘密鍵で署名します。-signkeyで秘密鍵を指定します。-daysで有効期間を指定します。有効期間は3年(1095日)とします。証明書は/etc/pki/CA/certs/niikawa-test-cacert.pem として配置します。

# openssl genrsa 2048 > /etc/pki/CA/private/niikawa-test-ca.key
Generating RSA private key, 2048 bit long modulus
......+++
....+++
e is 65537 (0x10001)
# openssl req -new -key /etc/pki/CA/private/niikawa-test-ca.key -sha256 -out /etc/pki/CA/niikawa-test-cacert.csr
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) [XX]:JP
State or Province Name (full name) []:Mie
Locality Name (eg, city) [Default City]:Kuwana
Organization Name (eg, company) [Default Company Ltd]:oji-cloud
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:niikawa-test-ca
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
# openssl x509 -days 1095 -in /etc/pki/CA/niikawa-test-cacert.csr -req -signkey /etc/pki/CA/private/niikawa-test-ca.key -out /etc/pki/CA/certs/niikawa-test-cacert.pem
Signature ok
subject=/C=JP/ST=Mie/L=Kuwana/O=oji-cloud/CN=niikawa-test-ca
Getting Private key

 

CRL(証明書失効リスト)の作成

  • 次にCAとして管理するCRL(証明書失効リスト)を作成します。CRLは、失効した公開鍵証明書のリスト(証明書のシリアル番号のリスト)です。CRLがない場合、次の証明書作成でエラーとなります。今回はテストのため、証明書のシリアル番号は"0x1″ とします。本来はもっと桁数の多いシリアル番号です。
  • 有効(Valid)な証明書は、index.txt の先頭に“V" がマークされます。失効された(Revoked)証明書は、先頭に“R"がマークされます。

# touch /etc/pki/CA/index.txt
# echo 01 > /etc/pki/CA/serial

 

自己署名証明書の作り方

  • openssl genrsaコマンドで、RSA 2048 bit の秘密鍵を作成します。秘密鍵は、/etc/pki/tls/private/niikawa-test-servercert.key として配置しています。
  • openssl reqコマンドで上記秘密鍵を使用して、CSRを作成します。-keyで秘密鍵を指定します。証明書の署名アルゴリズムにSHA-256を指定します。CSRは、/etc/pki/tls/niikawa-test-servercert.csr として配置しています。
  • openssl caコマンドで、サーバー証明書を発行します。-inでCSRを指定します。CAの秘密鍵で署名します。-keyfileで秘密鍵を指定します。-certでCAの証明書を指定します。-daysで有効期間を指定します。有効期間は3年(1095日)とします。証明書は/etc/pki/tls/certs/niikawa-test-servercert.pem として配置します。

# openssl genrsa 2048 > /etc/pki/tls/private/niikawa-test-servercert.key
Generating RSA private key, 2048 bit long modulus
........................................................................+++
...................................................................................................................................................+++
e is 65537 (0x10001)
# openssl req -new -key /etc/pki/tls/private/niikawa-test-servercert.key -sha256 -out /etc/pki/tls/niikawa-test-servercert.csr
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) [XX]:JP
State or Province Name (full name) []:Mie
Locality Name (eg, city) [Default City]:Kuwana
Organization Name (eg, company) [Default Company Ltd]:oji-cloud
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:niikawa-test-http.oji-cloud.net
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
# openssl ca -days 1095 -in /etc/pki/tls/niikawa-test-servercert.csr -out /etc/pki/tls/certs/niikawa-test-servercert.pem -keyfile /etc/pki/CA/private/niikawa-test-ca.key -cert /etc/pki/CA/certs/niikawa-test-cacert.pem
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Sep 24 12:33:47 2020 GMT
            Not After : Sep 24 12:33:47 2023 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Mie
            organizationName          = oji-cloud
            commonName                = niikawa-test-http.oji-cloud.net
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                35:D0:A1:40:EC:F3:8D:C9:FC:16:E2:7B:69:55:C7:0E:46:1D:F1:6B
            X509v3 Authority Key Identifier: 
                DirName:/C=JP/ST=Mie/L=Kuwana/O=oji-cloud/CN=niikawa-test-ca
                serial:9F:CC:AC:49:33:C1:34:FD

Certificate is to be certified until Sep 24 12:33:47 2023 GMT (1095 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
# 

 

  • 下記の通り、CRL(証明書失効リスト)が更新されました。index.txtに証明書の情報が追加されています。有効(Valid)な証明書のため、"V"がマークされています。CAで失効された(Revoked)場合は、"R" がマークされます。
  • serialのシリアル番号がカウントアップし、次の証明書には"0x2″が使われます。

# cat /etc/pki/CA/index.txt
V       230924123347Z           01      unknown /C=JP/ST=Mie/O=oji-cloud/CN=niikawa-test-http.oji-cloud.net
# cat /etc/pki/CA/serial
02

 

 

  • opensslコマンドで、発行された証明書の内容を確認します。

# openssl x509 -text -noout -in /etc/pki/tls/certs/niikawa-test-servercert.pem 
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1 (0x1)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=JP, ST=Mie, L=Kuwana, O=oji-cloud, CN=niikawa-test-ca
        Validity
            Not Before: Sep 24 12:33:47 2020 GMT
            Not After : Sep 24 12:33:47 2023 GMT
        Subject: C=JP, ST=Mie, O=oji-cloud, CN=niikawa-test-http.oji-cloud.net
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:c8:0b:07:48:f4:f1:ed:21:13:fd:94:b3:6c:bf:
                    f8:a6:ce:5c:94:85:9f:e0:40:d2:26:f2:f7:54:5e:
                    59:60:39:96:c9:48:fc:bf:a4:67:dc:64:f2:50:76:
                    33:37:3f:9c:b0:06:df:fa:a2:11:3d:84:63:e1:8f:
                    25:23:c1:f6:df:da:ff:d0:21:70:f6:f4:42:5d:af:
                    2c:83:0e:42:fc:91:85:24:4e:f1:ae:a7:45:e4:44:
                    ba:73:c4:d4:1a:78:22:98:ee:8b:8a:ec:90:e6:6b:
                    f8:62:a0:d9:5a:3d:06:da:9c:e6:72:ff:2d:fe:e9:
                    06:dd:2c:71:d4:6e:90:b7:02:9f:0f:ea:2c:b6:07:
                    c9:a8:74:74:a6:db:90:05:75:19:bb:05:f8:e4:5c:
                    54:22:6d:df:d8:9c:ed:e7:5a:da:a3:ba:98:be:62:
                    b0:2d:5f:c7:62:29:50:65:59:bd:0e:ce:17:c5:dc:
                    19:24:6d:38:06:08:0c:81:3b:26:84:d9:89:aa:a6:
                    4d:1d:bb:d2:b2:04:82:90:9b:df:31:65:b7:91:e3:
                    81:08:6b:03:58:c9:4a:73:d7:50:d7:c1:99:21:81:
                    41:db:1f:c4:48:56:35:ef:d4:10:e2:b9:9e:70:9b:
                    9a:a0:ba:23:96:c6:ab:f9:71:ec:ed:5d:67:63:c7:
                    3f:8b
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                35:D0:A1:40:EC:F3:8D:C9:FC:16:E2:7B:69:55:C7:0E:46:1D:F1:6B
            X509v3 Authority Key Identifier: 
                DirName:/C=JP/ST=Mie/L=Kuwana/O=oji-cloud/CN=niikawa-test-ca
                serial:9F:CC:AC:49:33:C1:34:FD

    Signature Algorithm: sha256WithRSAEncryption
         bd:40:7e:ec:c3:ca:dd:80:d4:8c:53:28:72:70:62:62:ca:27:
         7c:c1:9b:49:f4:cd:c3:ac:43:68:1c:db:fa:2e:29:06:61:b6:
         4a:ef:6b:fa:fb:cf:1a:0c:d0:d5:7d:3d:85:65:3d:95:63:ca:
         70:88:90:43:ba:df:cc:a7:94:18:16:9b:ff:4f:e6:69:3a:6c:
         26:e4:fd:48:92:29:f3:78:d6:6a:e9:b2:e1:8c:6d:35:a4:a0:
         34:6b:44:5e:e3:a3:c9:ab:60:ac:d1:8d:51:f4:d7:19:ea:d5:
         5a:64:c9:05:3f:8c:61:72:b8:47:59:fb:3b:ce:b0:73:ae:11:
         f5:20:0e:e7:97:a3:50:be:a0:cf:3e:6f:7d:ef:49:f2:47:ae:
         e0:17:e5:64:cf:4f:cd:fb:c8:c6:81:d8:4d:da:e8:91:e7:0e:
         f1:bc:70:de:9b:da:fa:25:0a:f5:b1:97:15:57:a0:77:b3:7d:
         61:a6:13:72:46:b7:3d:1c:c7:f5:59:a5:40:75:e1:6a:53:2a:
         d2:94:24:6f:a8:3b:2f:d6:21:b1:3a:6e:72:8f:da:e9:95:18:
         28:78:d6:38:25:05:eb:df:65:06:9f:0e:6e:40:b7:2c:b1:f5:
         53:96:e3:6e:fb:88:14:a8:30:3d:14:27:4e:d0:8e:9a:1f:20:
         a4:09:2b:a8

 

 

Apacheに証明書と秘密鍵を配置

  • /etc/httpd/conf.d/ssl.conf に証明書および秘密鍵を指定します。vhost を作成している場合は、vhostのconf を編集します。
#   Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate.  If
# the certificate is encrypted, then you will be prompted for a
# pass phrase.  Note that a kill -HUP will prompt again.  A new
# certificate can be generated using the genkey(1) command.
SSLCertificateFile /etc/pki/tls/certs/niikawa-test-servercert.pem ← 変更

#   Server Private Key:
#   If the key is not combined with the certificate, use this
#   directive to point at the key file.  Keep in mind that if
#   you've both a RSA and a DSA private key you can configure
#   both in parallel (to also allow the use of DSA ciphers, etc.)
SSLCertificateKeyFile /etc/pki/tls/private/niikawa-test-servercert.key ← 変更

#   Certificate Authority (CA):
#   Set the CA certificate verification path where to find CA
#   certificates for client authentication or alternatively one
#   huge file containing all of them (file must be PEM encoded)
SSLCACertificateFile /etc/pki/CA/certs/niikawa-test-cacert.pem ← 変更
  • httpdを再起動します。
# systemctl restart httpd

 

curl 疎通確認

/etc/ssl/certsにCA証明書を配置する

  • クライアントからcurl を実行します。今回、クライアントにはCA証明書が存在しないため、/etc/ssl/certsにCA証明書を配置しています。
  • しかし、今回は自己証明書を利用しているため、“SSL certificate problem" が出力されました。"self signed certificate in certificate chain" とあり、自己署名証明書のためエラーとなっているようです。
niikawa@niikawa1:~$ curl -vv https://niikawa-test-http.oji-cloud.net
* Rebuilt URL to: https://niikawa-test-http.oji-cloud.net/
*   Trying XX.XX.XX.XX...
* TCP_NODELAY set
* Connected to niikawa-test-http.oji-cloud.net (XX.XX.XX.XX) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS alert, Server hello (2):
* SSL certificate problem: self signed certificate in certificate chain
* stopped the pause stream!
* Closing connection 0
curl: (60) SSL certificate problem: self signed certificate in certificate chain
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

 

自己署名証明書利用時に指定するcurl オプション

  • 自己署名証明書利用時に出力された"SSL certificate problem" を回避するため、curl に“–insecure"オプションを追加します。次は無事にリクエストが送られ、レスポンス 200 OK も返りました。
niikawa@niikawa1:~$ curl -vv https://niikawa-test-http.oji-cloud.net --insecure
* Rebuilt URL to: https://niikawa-test-http.oji-cloud.net/
*   Trying XX.XX.XX.XX...
* TCP_NODELAY set
* Connected to niikawa-test-http.oji-cloud.net (XX.XX.XX.XX) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: C=JP; ST=Mie; O=oji-cloud; CN=niikawa-test-http.oji-cloud.net
*  start date: Sep 24 12:33:47 2020 GMT
*  expire date: Sep 24 12:33:47 2023 GMT
*  issuer: C=JP; ST=Mie; L=Kuwana; O=oji-cloud; CN=niikawa-test-ca
*  SSL certificate verify result: self signed certificate in certificate chain (19), continuing anyway.
> GET / HTTP/1.1
> Host: niikawa-test-http.oji-cloud.net
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Thu, 24 Sep 2020 16:36:19 GMT
< Server: Apache/2.4.46 () OpenSSL/1.0.2k-fips
< Upgrade: h2,h2c
< Connection: Upgrade
< Last-Modified: Thu, 24 Sep 2020 07:29:39 GMT
< ETag: "d-5b00a29b46f92"
< Accept-Ranges: bytes
< Content-Length: 13
< Content-Type: text/html; charset=UTF-8
<
niikawa-test
* Connection #0 to host niikawa-test-http.oji-cloud.net left intact

 

参考資料