🦥

オレオレ証明書チェーンを作成してみた

2024/07/27に公開

TL;DR

証明書チェーンの理解の為に、ルート証明書・中間証明書・サーバー証明書を作成して、Dockerコンテナ間の通信に使用できるようにしてみました。サーバー側にnginx、クライアント側にはopenssl, nmapを使用しています。curlでも通信可能です。

https://github.com/NaGaii1994/oreorepki/

証明書チェーンとは

証明書チェーンは、ルート証明書から中間証明書、そしてリーフ証明書(エンドエンティティ証明書)までの一連の証明書の連鎖を指します。このチェーンにより、信頼のあるルート証明書から最終的にリーフ証明書までの署名が検証され、通信相手が正しいことを確認できます。

証明書チェーンの作り方(抜粋)

内容はこちらのMakefileと殆ど同じになります。

  1. ルート証明書の作成
# ルートCAの秘密鍵生成(自己証明書)
openssl genpkey -algorithm RSA -out .keys/rootCA.key
# ルート証明書の作成要求 (CSR)
openssl req -new -key .keys/rootCA.key -out .keys/rootCA.csr -subj "/C=JP/ST=Tokyo/L=Chiyoda-ku/O=MyOrg/OU=MyUnit/CN=RootCA"
# ルート証明書の生成
openssl x509 -req -days 3650 -in .keys/rootCA.csr -signkey .keys/rootCA.key -out .keys/rootCA.crt -extfile <(echo "basicConstraints=CA:TRUE")
  1. 中間証明書の作成
# 中間証明書用の秘密鍵の生成
openssl genpkey -algorithm RSA -out .keys/intermediateCA.key
# 中間証明書の作成要求 (CSR)
openssl req -new -key .keys/intermediateCA.key -out .keys/intermediateCA.csr -subj "/C=JP/ST=Tokyo/L=Chiyoda-ku/O=MyOrg/OU=MyUnit/CN=IntermediateCA"
# 中間証明書の生成
openssl x509 -req -days 1825 -in .keys/intermediateCA.csr -CA .keys/rootCA.crt -CAkey .keys/rootCA.key -CAcreateserial -out .keys/intermediateCA.crt -extfile <(echo "basicConstraints=CA:TRUE")
  1. リーフ(サーバー)証明書の作成
# サーバー証明書用の秘密鍵の生成
openssl genpkey -algorithm RSA -out .keys/server.key
# サーバー証明書の作成要求 (CSR)
openssl req -new -key .keys/server.key -out .keys/server.csr -subj "/C=JP/ST=Tokyo/L=Chiyoda-ku/O=MyOrg/OU=MyUnit/CN=www.tls-example.com"
# サーバー証明書の生成
openssl x509 -req -days 365 -in .keys/server.csr -CA .keys/intermediateCA.crt -CAkey .keys/intermediateCA.key -CAcreateserial -out .keys/server.crt

証明書のインストール・検証

内容はこちらのMakefileを参照してください。

OpenSSLコマンドによる証明書の検証
$ docker compose exec client bash -c "openssl s_client -showcerts -connect www.tls-example.com:443 </dev/null"
CONNECTED(00000003)
depth=2 C = JP, ST = Tokyo, L = Chiyoda-ku, O = MyOrg, OU = MyUnit, CN = RootCA
verify return:1
depth=1 C = JP, ST = Tokyo, L = Chiyoda-ku, O = MyOrg, OU = MyUnit, CN = IntermediateCA
verify return:1
depth=0 C = JP, ST = Tokyo, L = Chiyoda-ku, O = MyOrg, OU = MyUnit, CN = www.tls-example.com
verify return:1
---
Certificate chain
 0 s:C = JP, ST = Tokyo, L = Chiyoda-ku, O = MyOrg, OU = MyUnit, CN = www.tls-example.com
   i:C = JP, ST = Tokyo, L = Chiyoda-ku, O = MyOrg, OU = MyUnit, CN = IntermediateCA
-----BEGIN CERTIFICATE-----
MIIDrTCCApWgAwIBAgIUBjie3QZORxqM2hqGqbfSKzRCwZ0wDQYJKoZIhvcNAQEL
BQAwbDELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRva3lvMRMwEQYDVQQHDApDaGl5
b2RhLWt1MQ4wDAYDVQQKDAVNeU9yZzEPMA0GA1UECwwGTXlVbml0MRcwFQYDVQQD
DA5JbnRlcm1lZGlhdGVDQTAeFw0yNDA3MjcwOTAzNTVaFw0yNTA3MjcwOTAzNTVa
MHExCzAJBgNVBAYTAkpQMQ4wDAYDVQQIDAVUb2t5bzETMBEGA1UEBwwKQ2hpeW9k
YS1rdTEOMAwGA1UECgwFTXlPcmcxDzANBgNVBAsMBk15VW5pdDEcMBoGA1UEAwwT
d3d3LnRscy1leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAK1DQ5xi3tE4KmMKkT/tccxCtohDewGBxvGYjkmXzypfEyaW3dpgIC9Dy3MB
6AAEbAWKCgULn/gEn/ZF5CRFij1ciF6JsVpM2lr954xpnew2+K8K/0KF+BXYY9TL
2JzYSfp/BUX9Zr3jKCwkL0m1c/W7vJauq7AVk89VVIqG7kKBj6HCHtJgoGjqYyzo
r2XLRmg+jErXki8dPO6/GcWYbszMAt1Gl8bgOqW+G9jIAExVmRZj+s5L9gO57Xsd
9YmCgD64mVygb54uW6V/EApeHQWdcXw/S5Cv/g1vFovljHdZbzaxY3WNcf4HIHRG
1GR09JxQlk8bSSUMa+Y0GuGAvjUCAwEAAaNCMEAwHQYDVR0OBBYEFIvvWsGkotI8
kJZxN5KUCxrVYEv0MB8GA1UdIwQYMBaAFP3jq9RKYJHxwYBbTlj1BK8xpkLKMA0G
CSqGSIb3DQEBCwUAA4IBAQAmALqDZz9rE+dpDge61i0plLJe7V99fC0xerMadcGE
oJxIBiaVNJ0mEpPAaDbv0l8Xde4Uscwv7uyXupx26nzxQ9oYBtfCmGdPpl25yztw
paasvzmZsaUW3kon8aO36mmTUSR2t3aOF3mYvH4gnXSpfkUzp3YY5wxwFjTNET1+
Oiz1N2HU58xhZ03yoUVoXOZGBXkN1h0uWGK6GdHSNGB9gzGqEhkBVcNSDiNthmvP
insxRPwcxkwDQDWQVtv0F1FpAYUEfQvBqPkeUPnIPCAJpZFiPpts2odcIgAKCq6O
JUJOYRQZdqOzGZ/gZF7IwjvWEnLBNoqvmdilR926jUM4
-----END CERTIFICATE-----
 1 s:C = JP, ST = Tokyo, L = Chiyoda-ku, O = MyOrg, OU = MyUnit, CN = IntermediateCA
   i:C = JP, ST = Tokyo, L = Chiyoda-ku, O = MyOrg, OU = MyUnit, CN = RootCA
-----BEGIN CERTIFICATE-----
MIIDrjCCApagAwIBAgIUJ/DH6RyirEtjR0KISAK+gBfYzMMwDQYJKoZIhvcNAQEL
BQAwZDELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRva3lvMRMwEQYDVQQHDApDaGl5
b2RhLWt1MQ4wDAYDVQQKDAVNeU9yZzEPMA0GA1UECwwGTXlVbml0MQ8wDQYDVQQD
DAZSb290Q0EwHhcNMjQwNzI3MDkwMzU1WhcNMjkwNzI2MDkwMzU1WjBsMQswCQYD
VQQGEwJKUDEOMAwGA1UECAwFVG9reW8xEzARBgNVBAcMCkNoaXlvZGEta3UxDjAM
BgNVBAoMBU15T3JnMQ8wDQYDVQQLDAZNeVVuaXQxFzAVBgNVBAMMDkludGVybWVk
aWF0ZUNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArsbXh/xK/Z9j
ALU4+lY0dKMzk5WFt96XZyP1EX/Y5srXPwxgGXRHQiqevrugleM9XeGnIW9aRCiO
+wrzvtu78Pcv2k2spvrG80ZNc9d6TGv/qPUxF+OLWpWnXTC+vTG89bJbM+OFVAn+
2EKQzb5GvSNzPxdgQTZfmmMpotpKZ0sxU1Ih37SXTlKI2IyXwuTuqZPws2bXFmDc
G7kXbmThm1pWtuSOdutFeDnd3zitd9aueFIwE5/2TN6VxUZakMCg2CVc1f4B1A0y
4R/D8NPBxOVRsvVo9Z34lfZpK6C24KX0rOtRoaZ+ulCTpPAKi7o11S5jAWbDrCny
wtadQj9vFwIDAQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBT946vUSmCR
8cGAW05Y9QSvMaZCyjAfBgNVHSMEGDAWgBRPI3EMfDfjswKfkqorPxdV3OtkzTAN
BgkqhkiG9w0BAQsFAAOCAQEAygE/AuC/cykhcmqsmoFy76M726RDUpXgSrZG2ozM
IhnX2+AhYJBy71NlXRwOyjQy261iSUAJXDvi6iD1tQZSPZIFpgVYJTH9qm8X/+Lu
NDMDismweZnPHwfnBGprepzJsFSAB/iz8+Kc4AejUsuEGE9L4sjzCZnSjN/+BYEs
kXLHW9/E65my+FIx7PTKDMXWICbZakuRLg4w1NZwQPZykFI62d0yYDIZdhEZvCcq
GXu8BC31sDCxyrPYf8uX/s5+dau0gq6luTZR6gAf2ybJrG/pAC9lB+ECwG15h157
NDa22HctwAUO2pTYnpLQncM3hqPEm4NElYPivOj6yMUHrw==
-----END CERTIFICATE-----
---
Server certificate
subject=C = JP, ST = Tokyo, L = Chiyoda-ku, O = MyOrg, OU = MyUnit, CN = www.tls-example.com

issuer=C = JP, ST = Tokyo, L = Chiyoda-ku, O = MyOrg, OU = MyUnit, CN = IntermediateCA

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 2571 bytes and written 404 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: BD001C9888B84D375819D91FF8992BC660FC2334CB428455B68144F25B4AB662
    Session-ID-ctx: 
    Master-Key: C069351EF26BDD10EAD2044AF474D6D444E9CE140BD8BDF0F567FDD2C81139A832F96504E22A739C784D0199B83344D1
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - 68 4e c9 96 2d 9a a9 79-ef e2 98 a2 87 94 01 f5   hN..-..y........
    0010 - b8 e9 0f 18 c9 ca 24 8b-c3 63 c7 3d 70 34 8d 12   ......$..c.=p4..
    0020 - 48 18 65 d6 03 a0 ab 0d-1c 5f fa e5 53 61 e8 1d   H.e......_..Sa..
    0030 - 45 cc d5 8a f8 75 dc 99-e4 fd 89 e2 59 e2 6b 06   E....u......Y.k.
    0040 - 29 c7 72 d2 40 14 8f d2-73 92 de a2 65 3b a0 8d   ).r.@...s...e;..
    0050 - 86 01 4d 8b 46 2f db 65-9d 8d 8c e0 77 8b dd 51   ..M.F/.e....w..Q
    0060 - b1 a0 b5 28 ca c4 24 ca-a3 41 ab 89 f6 6f 5c b3   ...(..$..A...o\.
    0070 - ae 81 5d 0c 5f a5 a9 87-d3 a5 16 51 22 89 37 94   ..]._......Q".7.
    0080 - b0 b6 cb 2e 4b 1a 8c 5e-c6 6a 1f e9 75 e2 20 ce   ....K..^.j..u. .
    0090 - b0 7b dc c3 b0 2a 37 7a-fa 6f ae 87 63 0f ad 90   .{...*7z.o..c...
    00a0 - d0 45 33 c9 ef 88 ad 69-d7 60 d0 bc 0c 7b ac db   .E3....i.`...{..
    00b0 - 26 7d e6 41 7b 68 c4 7a-39 08 85 b2 2d 67 f0 c3   &}.A{h.z9...-g..
    00c0 - 68 16 54 d7 c0 0b da 41-98 8c cd bb 2b 9c ad 67   h.T....A....+..g

    Start Time: 1722071091
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: yes
---
DONE
Nmapによる使用できるtlsバージョンと暗号スイートの一覧の表示
docker compose exec client bash -c "nmap --script ssl-enum-ciphers -p 443 www.tls-example.com"
Starting Nmap 7.80 ( https://nmap.org ) at 2024-07-27 09:04 UTC
Nmap scan report for www.tls-example.com (172.20.0.2)
Host is up (0.000044s latency).
rDNS record for 172.20.0.2: dump_tls-www.tls-example.com-1.dump_tls_default

PORT    STATE SERVICE
443/tcp open  https
| ssl-enum-ciphers: 
|   TLSv1.2: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (ecdh_x25519) - A
|       TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (ecdh_x25519) - A
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (ecdh_x25519) - A
|     compressors: 
|       NULL
|     cipher preference: server
|_  least strength: A
MAC Address: 02:42:AC:14:00:02 (Unknown)

Nmap done: 1 IP address (1 host up) scanned in 0.20 seconds

Discussion