【Linux】SSL/TLS証明書作成

拡張子がややこしい…

# ■証明書作成の流れ

ステップ1: RSA秘密鍵（private.key）を生成
(Option): ルートCA証明書（rootCA.pem）を生成
ステップ2: 証明書署名要求（CSR、server.csr）を生成
ステップ3: CSRをもとにサーバ証明書（server.crt）を生成

## 1.秘密鍵を作成する
```
# openssl genrsa -out private.key 2048
```
`genrsa`: RSA秘密鍵を生成
`-out private.key`: 出力先ファイルとしてprivate.keyを指定(拡張子は.pemの場合もある)
`2048`: 鍵の長さを2048ビットに指定

秘密鍵が生成されるが、その中には対応する公開鍵の情報も含まれている。
公開鍵をエクスポートしたいときは以下コマンド
```
# openssl rsa -in private.key -pubout -out public-key.pem
```
`rsa`: RSAの秘密鍵や公開鍵の操作を行う
`-in private.key`: 入力ファイルとして秘密鍵を指定
`-pubout`: 公開鍵を出力するよう指定
`-out public.pem`: 出力ファイルとして公開鍵を指定

## (option): 自己署名のルートCA証明書を作成
サーバで自己署名(self-signed)のルートCA証明書を生成する。※ローカルCA証明書ともいう
プライベートな認証局(内部認証基盤)を設定する際に使用される
```
# openssl req -x509 -new -nodes -key private.key -sha256 -days 1024 -out rootCA.pem
```
`req`: 証明書署名要求（CSR）を作成または処理する
`-x509`: 自己署名証明書を生成する。このオプションがない場合はCSRが生成される
`-new`: 新しいCSRまたは証明書を生成する
`-nodes`: 秘密鍵をパスフレーズで暗号化しないように指定
`-key private.key`: 自己署名に使用する秘密鍵ファイルを指定
`-sha256`: 証明書にSHA-256ハッシュアルゴリズムを使用
`-days 1024`: 証明書の有効期限を1024日に設定
`-out rootCA.pem`: 生成された自己署名証明書の出力先ファイルを指定

## 2.CSRを作成
サーバ証明書のための証明書署名要求（CSR）を生成する。
```
# openssl req -new -key private.key -out server.csr
```
`req`: 証明書署名要求（CSR）を作成または処理する
`-new`: 新しいCSRまたは証明書を生成する.※ここでは-x509オプションがないため、CSRが作成される
`-key private.key`: CSR作成に使用する秘密鍵を指定
`-out server.csr`: 生成されたCSRの出力先ファイルを指定

## 3.CSRをもとにサーバ証明書を生成
CSRをシマンテックなどの正式な認証局に送り、認められればサーバ証明書が返送される。
自己署名（いわゆるオレオレ証明書）にする場合は以下

```
# (option)で作成したルートCA証明書を使って作成する場合
# openssl x509 -req -days 365 -in server.csr -CA rootCA.pem -CAkey private.key -CAcreateserial -out server.crt -extfile san.txt
```
```
# 秘密鍵で直接署名して作成する場合
# openssl x509 -req -days 365 -in server.csr -signkey private.key -out server.crt -extfile san.txt
```
`x509`: X.509形式の証明書処理を行う
`-req`: CSRから情報を取得して証明書を発行する
`-days 365`: 証明書の有効期限を365日に設定
`-in server.csr`: 入力ファイルとしてCSR（server.csr）を指定
`-CA`: ルートCA証明書ファイルを指定
`-signkey private.key`: 証明書署名に使用する秘密鍵（private.key）を指定
`-out server.crt`: 生成された証明書の出力先ファイルを指定
`-extfile san.txt`: 証明書の拡張設定（例：Subject Alternative Names）を指定したファイルを読み込む

### -extfile san.txt
拡張設定の例。ここではサーバ証明書にドメイン名（SAN：Subject Alternative Names）を追加している。
なしで作成すると以下のようなエラーが出る場合があり…↓
```
ERRO[2024-08-08 23:02:14] Failed verifying certificate: x509: certificate relies on legacy Common Name field, use SANs instead 
ERRO[2024-08-08 23:02:14] An error occurred: x509: certificate relies on legacy Common Name field, use SANs instead 
```
ので、テキストファイルに拡張設定を書いて指定する
```:san.txt
subjectAltName = @alt_names

[alt_names]
DNS.1 = www.example.com
DNS.2 = example.com
```

https://qiita.com/ShotaImoto1/items/a2a9e9c064c9d1b4ed32


# ■作成例
```console:
[root@host01 ~]# openssl genrsa -out private.key 2048    #秘密鍵作成
Generating RSA private key, 2048 bit long modulus
....................................+++
............................................................+++
e is 65537 (0x10001)
[root@host01 ~]# 
[root@host01 ~]# ls
private.key
[root@host01 ~]# 
[root@host01 ~]# cat private.key 
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAv9bwNG3hA
(略)
dczV46uEYrM/oUur95a1KZRSh
-----END RSA PRIVATE KEY-----
[root@host01 ~]# 
[root@host01 ~]# openssl req -new -key private.key -out server.csr   #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) []:Tokyo
Locality Name (eg, city) [Default City]:Raccoon City
Organization Name (eg, company) [Default Company Ltd]:Umbrella
Organizational Unit Name (eg, section) []:human experiment Unit                                                    
Common Name (eg, your name or your server's hostname) []:host01.local
Email Address []:hogehoge.co.jp

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@host01 ~]# 
[root@host01 ~]# ls
private.key  server.csr
[root@host01 ~]# cat server.csr
-----BEGIN CERTIFICATE REQUEST-----
MIIC4zCCAcsCAQAwgZ0xCzAJBgNVBAYTAkpQMQ4wDAYDVQQIDAVUb2t5bzEVMBMG
(略)
obc/VkE6A/q7OJa6u5efANIn8Tcj4L4=
-----END CERTIFICATE REQUEST-----
[root@host01 ~]# 

[root@host01 ~]# vi san.txt
[root@host01 ~]# cat san.txt
subjectAltName = DNS:example.com
[root@host01 ~]#
[root@host01 ~]# openssl x509 -req -days 365 -in server.csr -signkey private.key -out server.crt -extfile san.txt     #秘密鍵で署名してサーバ証明書作成
Signature ok
subject=/C=JP/ST=Tokyo/L=Raccoon City/O=Umbrella/OU=human experiment Unit/CN=host01.local/emailAddress=hogehoge.co.jp
Getting Private key
[root@host01 ~]# 
[root@host01 ~]# ls
private.key  san.txt  server.crt  server.csr
[root@host01 ~]# 
[root@host01 ~]# cat server.crt
-----BEGIN CERTIFICATE-----
MIID2TCCAsGgAwIBAgIJAOy0I96HysgOMA0GCSqGSIb3DQEBCwUAMIGdMQswCQYD
(略)
gPh37FrGGL+hZnn8fSD2JlO4ENoDPkZhjP7Ywso=
-----END CERTIFICATE-----
[root@host01 ~]# 
[root@host01 ~]# openssl x509 -text -in server.crt -noout     #サーバ証明書確認
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            ec:b4:23:de:87:ca:c8:0e
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=JP, ST=Tokyo, L=Raccoon City, O=Umbrella, OU=human experiment Unit, CN=host01.local/emailAddress=hogehoge.co.jp
        Validity
            Not Before: Dec  4 14:31:37 2024 GMT
            Not After : Dec  4 14:31:37 2025 GMT
        Subject: C=JP, ST=Tokyo, L=Raccoon City, O=Umbrella, OU=human experiment Unit, CN=host01.local/emailAddress=hogehoge.co.jp
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:bf:d6:f0:34:6d:e1:01:c4:c6:ca:1e:e3:4e:5c:
                    1e:25:d1:52:eb:36:fb:bc:24:35:23:d9:a4:cd:4c:
                    ba:9d:6f:20:19:2c:4b:4c:11:2b:e8:6f:0f:80:8f:
                    aa:76:88:89:bc:1f:78:7f:a3:f8:f1:4a:01:1f:73:
                    71:52:aa:20:82:a1:38:93:ec:f6:cf:75:68:8f:ff:
                    ce:82:f6:4f:51:01:e3:bd:b6:b8:fc:98:9d:d0:80:
                    2f:29:3c:ac:54:ab:b1:c6:ee:5b:8f:f2:4d:0a:4a:
                    76:2b:cc:c1:9f:24:93:18:66:85:bb:3e:8b:80:b1:
                    d1:96:d9:3d:eb:dc:80:84:7d:71:d6:ef:c1:1e:cd:
                    6b:08:29:7c:6d:00:f9:51:ff:d8:8e:3b:77:26:0e:
                    66:ca:c9:17:c2:ff:a8:e3:1a:83:f8:24:24:4f:6a:
                    6f:0c:8d:71:e9:3d:c5:2f:80:4a:52:32:bf:dd:54:
                    2d:98:fd:47:21:09:51:59:07:36:13:2a:f0:e7:19:
                    ee:d1:39:f9:c3:d2:f6:bb:bc:d2:92:92:bc:10:27:
                    1c:6d:75:42:fc:68:50:f5:23:88:8d:de:0b:39:38:
                    64:b5:8b:6b:3d:dc:0c:bd:99:99:97:3f:86:ef:fa:
                    71:e4:c6:e3:08:f3:a7:0f:62:40:62:62:06:be:06:
                    cd:d3
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Alternative Name: 
                DNS:example.com
    Signature Algorithm: sha256WithRSAEncryption
         24:d5:3f:6c:d0:00:68:a2:8e:b1:fb:33:c2:53:ce:0e:af:96:
         b3:07:3b:81:96:bc:25:0c:a0:99:2a:8b:15:6e:0b:d5:46:46:
         72:0e:c1:dc:dc:be:04:f7:42:9f:f0:16:8d:06:4e:80:59:cb:
         13:17:d4:c0:a3:bd:fe:af:bb:83:51:e7:e8:18:84:ec:03:21:
         45:86:4a:a0:3a:69:30:76:69:06:e3:f6:c6:cb:6e:57:7f:58:
         a8:6e:4d:01:e5:7e:15:5c:50:e4:3f:c6:86:d0:5e:82:5d:2a:
         8a:3b:c7:01:bb:fc:90:ab:0d:8c:ea:67:0d:c2:ff:fe:28:47:
         88:02:e6:8e:4d:46:8e:90:24:0e:55:11:e7:cf:92:3b:82:03:
         54:f8:8b:30:dd:97:2d:5d:61:84:11:49:37:45:9f:a9:b2:aa:
         c2:ee:da:64:00:cf:09:67:95:58:23:2e:02:60:b9:9d:c1:d0:
         54:3f:df:17:09:f8:b1:f0:11:ed:dd:07:27:5a:09:02:53:0b:
         f5:14:cf:9f:db:23:81:e4:a6:a7:f0:91:b0:4a:3c:f1:9e:4e:
         fb:8a:ee:fd:db:37:27:f3:2b:40:0d:80:f8:77:ec:5a:c6:18:
         bf:a1:66:79:fc:7d:20:f6:26:53:b8:10:da:03:3e:46:61:8c:
         fe:d8:c2:ca
```

# ■証明書登録
自己署名証明書や内部CAの証明書を使用している場合、その自己署名証明書を
`/etc/pki/ca-trust/source/anchors/`に配置することで、システム上のアプリケーションがその証明書を信頼できるようにする。
※実装しているシステム(Apatch,Nginx等)により異なるので注意

```
# cp my-ca-cert.pem /etc/pki/ca-trust/source/anchors/
```
信頼リスト更新/確認
```
# update-ca-trust extract
# trust list        # 信頼済みの証明書を一覧表示
```
ファイルとしては、
`/etc/pki/tls/certs/` または `/etc/ssl/certs/` ディレクトリの
`ca-bundle.crt` または `ca-bundle.trust.crt` 
にリストされる。（色んなところにあるな…）

# ■HTTPS通信確認
```
openssl s_client -connect xxxx.com:443
```
`openssl s_client`: OpenSSLコマンドでSSL/TLSクライアントを起動
`-connect xxxx.com:443`: 接続先のホスト名とポート番号を指定

このコマンドを実行すると、指定されたホストとポート上のサーバーに対してSSL/TLS接続が試みられる。
接続が成功すると、サーバーの証明書情報や使用されるSSL/TLSバージョンなどの詳細な情報が表示される。

証明書ファイルの内容を表示したい場合は以下
```
openssl x509 -in xxxx.crt -text -noout
```

# ■cURL確認(おまけ)
```
curl http://xxxx.com
```
`-L`:リダイレクトがあればリダイレクト先の情報を取得
`-s`:進捗状況を非表示。-sSとすることが多い
`-S`:エラーは表示。-sSとすることが多い
`-v`:詳細ログを出力
`-I`:HTTPレスポンスヘッダを取得
`-k`:SSL接続で証明書エラーをスキップ