CubicLouve

Spring_MTの技術ブログ

証明書と認証局の確認

まずは証明書周りについての整理

証明書

証明書は電子文書。

ja.wikipedia.org

証明書の中には、公開鍵やそれに紐づく情報と証明書の発行元のデジタル署名が含まれています。

現在の公開鍵基盤として広く使われているX.509では、証明書の構造は ASN.1 という記法で定義されています。

www.ipa.go.jp

ASN.1で定義された内容をネットワーク経由で送るには、これをビット列に符号化する必要があり、この符号化ルールの一つがDistinguished Encoding Rules (DER) 。

docs.microsoft.com

DERでエンコードされ更にbase64エンコードしたものがPEMとなります。

証明書でよく見かけるのはこのPEM形式です。

証明書の作成

opensslは1.1.1以降であればEd25519が使えるようになっているので、これを使ってみます。

www.openssl.org

jnst.hateblo.jp

qiita.com

今回手元で確認するだけなので、秘密鍵の内容も記載していますが、本来であれば絶対に記載してはいけない内容です。

% openssl version
OpenSSL 1.1.1g  21 Apr 2020
% openssl genpkey -algorithm ed25519 -out private.pem 

% openssl asn1parse -in private.pem
    0:d=0  hl=2 l=  46 cons: SEQUENCE          
    2:d=1  hl=2 l=   1 prim: INTEGER           :00
    5:d=1  hl=2 l=   5 cons: SEQUENCE          
    7:d=2  hl=2 l=   3 prim: OBJECT            :ED25519
   12:d=1  hl=2 l=  34 prim: OCTET STRING      [HEX DUMP]:042034E86A39818F82B908DB25D3C64ED4053ED47A7855C2CA9303B9866F193C82BE

% openssl pkey -in private.pem -outform DER | od -An -tx1
           30  2e  02  01  00  30  05  06  03  2b  65  70  04  22  04  20
           34  e8  6a  39  81  8f  82  b9  08  db  25  d3  c6  4e  d4  05
           3e  d4  7a  78  55  c2  ca  93  03  b9  86  6f  19  3c  82  be

秘密鍵を生成後にASN.1フォーマットを確認しています。

さらにバイナリにして確認しています。

id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 } なので、hexにすると 01 03 65 70 なんですが、なんか微妙に合わないけど、なんかまあ判別できそうな感じはします。

tools.ietf.org

  • CSR( Certificate Signing Request )の生成

次に証明書への署名をCAにリクエストするCSRを生成します。

% openssl req -new -out example.csr -key private.pem
% openssl asn1parse -in example.csr
    0:d=0  hl=3 l= 221 cons: SEQUENCE          
    3:d=1  hl=3 l= 144 cons: SEQUENCE          
    6:d=2  hl=2 l=   1 prim: INTEGER           :00
    9:d=2  hl=2 l=  93 cons: SEQUENCE          
   11:d=3  hl=2 l=  11 cons: SET               
   13:d=4  hl=2 l=   9 cons: SEQUENCE          
   15:d=5  hl=2 l=   3 prim: OBJECT            :countryName
   20:d=5  hl=2 l=   2 prim: PRINTABLESTRING   :JA
   24:d=3  hl=2 l=  14 cons: SET               
   26:d=4  hl=2 l=  12 cons: SEQUENCE          
   28:d=5  hl=2 l=   3 prim: OBJECT            :stateOrProvinceName
   33:d=5  hl=2 l=   5 prim: UTF8STRING        :Tokyo
   40:d=3  hl=2 l=  16 cons: SET               
   42:d=4  hl=2 l=  14 cons: SEQUENCE          
   44:d=5  hl=2 l=   3 prim: OBJECT            :localityName
   49:d=5  hl=2 l=   7 prim: UTF8STRING        :Shibuya
   58:d=3  hl=2 l=  12 cons: SET               
   60:d=4  hl=2 l=  10 cons: SEQUENCE          
   62:d=5  hl=2 l=   3 prim: OBJECT            :organizationName
   67:d=5  hl=2 l=   3 prim: UTF8STRING        :Foo
   72:d=3  hl=2 l=  12 cons: SET               
   74:d=4  hl=2 l=  10 cons: SEQUENCE          
   76:d=5  hl=2 l=   3 prim: OBJECT            :organizationalUnitName
   81:d=5  hl=2 l=   3 prim: UTF8STRING        :Bar
   86:d=3  hl=2 l=  16 cons: SET               
   88:d=4  hl=2 l=  14 cons: SEQUENCE          
   90:d=5  hl=2 l=   3 prim: OBJECT            :commonName
   95:d=5  hl=2 l=   7 prim: UTF8STRING        :footest
  104:d=2  hl=2 l=  42 cons: SEQUENCE          
  106:d=3  hl=2 l=   5 cons: SEQUENCE          
  108:d=4  hl=2 l=   3 prim: OBJECT            :ED25519
  113:d=3  hl=2 l=  33 prim: BIT STRING        
  148:d=2  hl=2 l=   0 cons: cont [ 0 ]        
  150:d=1  hl=2 l=   5 cons: SEQUENCE          
  152:d=2  hl=2 l=   3 prim: OBJECT            :ED25519
  157:d=1  hl=2 l=  65 prim: BIT STRING
% openssl req -text -in example.csr
Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = JA, ST = Tokyo, L = Shibuya, O = Foo, OU = Bar, CN = footest
        Subject Public Key Info:
            Public Key Algorithm: ED25519
                ED25519 Public-Key:
                pub:
                    4d:85:35:84:30:4b:78:27:e6:57:2b:cc:3c:e2:55:
                    f5:79:52:ec:53:7e:fa:2a:96:6a:bd:f3:39:1b:28:
                    6c:74
        Attributes:
            a0:00
    Signature Algorithm: ED25519
         3d:cb:8e:d1:83:11:b4:54:3e:e4:a8:a1:42:70:67:ce:bc:21:
         eb:e4:82:57:74:24:03:94:51:e1:bc:b9:06:e2:7d:9c:7e:4f:
         09:3a:c1:1f:7b:30:3d:01:16:f3:13:e1:78:b1:47:39:4c:7a:
         a8:95:a0:89:22:b7:0d:b2:58:03
-----BEGIN CERTIFICATE REQUEST-----
MIHdMIGQAgEAMF0xCzAJBgNVBAYTAkpBMQ4wDAYDVQQIDAVUb2t5bzEQMA4GA1UE
BwwHU2hpYnV5YTEMMAoGA1UECgwDRm9vMQwwCgYDVQQLDANCYXIxEDAOBgNVBAMM
B2Zvb3Rlc3QwKjAFBgMrZXADIQBNhTWEMEt4J+ZXK8w84lX1eVLsU376KpZqvfM5
GyhsdKAAMAUGAytlcANBAD3LjtGDEbRUPuSooUJwZ868Ievkgld0JAOUUeG8uQbi
fZx+Twk6wR97MD0BFvMT4XixRzlMeqiVoIkitw2yWAM=
-----END CERTIFICATE REQUEST-----

CSRには公開鍵が含まれています。(秘密鍵は含まれません。)

CSRを元に証明書を作成します。

下記は自分の秘密鍵で自己署名した自己署名証明書の作成の例です。(自己署名証明書であれば、秘密鍵だけでも作成可能です)

% openssl x509 -req -days 700 -in example.csr -signkey private.pem -out sample.crt 
% openssl x509 -text -in sample.crt
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            6b:c9:75:4e:4a:96:00:a3:b7:cf:c9:81:f1:70:16:4f:ca:b4:e2:5b
        Signature Algorithm: ED25519
        Issuer: C = JA, ST = Tokyo, L = Shibuya, O = Foo, OU = Bar, CN = footest
        Validity
            Not Before: Apr 28 07:13:16 2021 GMT
            Not After : Mar 29 07:13:16 2023 GMT
        Subject: C = JA, ST = Tokyo, L = Shibuya, O = Foo, OU = Bar, CN = footest
        Subject Public Key Info:
            Public Key Algorithm: ED25519
                ED25519 Public-Key:
                pub:
                    4d:85:35:84:30:4b:78:27:e6:57:2b:cc:3c:e2:55:
                    f5:79:52:ec:53:7e:fa:2a:96:6a:bd:f3:39:1b:28:
                    6c:74
    Signature Algorithm: ED25519
         bb:b6:68:cc:76:01:a4:38:7d:6c:4a:00:5e:c5:1f:f3:e8:f1:
         e8:0c:dc:62:03:bc:90:75:66:f0:d7:38:9a:cb:60:23:be:0a:
         b1:76:47:45:81:5a:5f:4c:0f:52:41:4a:9f:99:de:c5:1f:47:
         ac:75:44:3a:f4:8d:24:50:c1:00
-----BEGIN CERTIFICATE-----
MIIBdTCCAScCFGvJdU5KlgCjt8/JgfFwFk/KtOJbMAUGAytlcDBdMQswCQYDVQQG
EwJKQTEOMAwGA1UECAwFVG9reW8xEDAOBgNVBAcMB1NoaWJ1eWExDDAKBgNVBAoM
A0ZvbzEMMAoGA1UECwwDQmFyMRAwDgYDVQQDDAdmb290ZXN0MB4XDTIxMDQyODA3
MTMxNloXDTIzMDMyOTA3MTMxNlowXTELMAkGA1UEBhMCSkExDjAMBgNVBAgMBVRv
a3lvMRAwDgYDVQQHDAdTaGlidXlhMQwwCgYDVQQKDANGb28xDDAKBgNVBAsMA0Jh
cjEQMA4GA1UEAwwHZm9vdGVzdDAqMAUGAytlcAMhAE2FNYQwS3gn5lcrzDziVfV5
UuxTfvoqlmq98zkbKGx0MAUGAytlcANBALu2aMx2AaQ4fWxKAF7FH/Po8egM3GID
vJB1ZvDXOJrLYCO+CrF2R0WBWl9MD1JBSp+Z3sUfR6x1RDr0jSRQwQA=
-----END CERTIFICATE-----

自己署名した証明書を検証してみます。

% openssl verify -CAfile sample.crt sample.crt 
sample.crt: OK

検証とは

www.nic.ad.jp

CA

基本的に証明書の発行はCA(認証局)が行います。

CAはCSRを受け取ると、CSRから公開鍵を取得します。

また、CSRに基づいて証明書の種類に応じた検証(本人確認など)を行います。

確認が終わったら、証明書を作成します。

証明書を作成する際は、証明書にデジタル署名します。

ここでのデジタル署名では、CAの秘密鍵を使って行います。

また、署名に使うハッシュ関数CSRで指定できないので事前に確認が必要です。

自前でCAを作ってみる

よくある話ですが、自前でCAを作って証明書の発行をやってみます。

opensslにはCAを作るコマンドが同梱されています。

github.com

cnfは下記をコピーして使いました。

openssl/openssl.cnf at 4489655c23f1f7f412309e25a5b9fd7acf7db3f2 · openssl/openssl · GitHub

root CAを作る

% OPENSSL=/Users/hoge/http_sample/openssl/apps/openssl OPENSSL_CONFIG="-config ./openssl.cnf" ./CA.pl -newca
CA certificate filename (or enter to create)

Making CA certificate ...
====
/Users/haruyama.makoto/http_sample/openssl/apps/openssl req -config ./openssl.cnf -new -keyout ./demoCA/private/cakey.pem -out ./demoCA/careq.pem 
Generating a RSA private key
.....+....+..+....+...+...+..+...+.............+.....+......+.+..+...+...+.......+..............+.........+.........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.....+..+...+....+..+......+....+...........+...+....+...+...+.....+..........+.....+.+..............+......+.+..+.......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.........+.+...+..+.......+......+..+....+.....+....+............+.........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.....+.+.........+..+....+.....+..........+...........+...................+..+....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+........+....+.....+.........+......+...+...+............+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Writing new private key to './demoCA/private/cakey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
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) [AU]:JA
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:Shibuya
Organization Name (eg, company) [Internet Widgits Pty Ltd]:CaSample
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:ca-sample.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
==> 0
====
====
/Users/hoge/http_sample/openssl/apps/openssl ca -config ./openssl.cnf -create_serial -out ./demoCA/cacert.pem -days 1095 -batch -keyfile ./demoCA/private/cakey.pem -selfsign -extensions v3_ca -infiles ./demoCA/careq.pem 
Using configuration from ./openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            5f:ea:3f:e3:bf:eb:68:e3:13:1c:b4:96:eb:ef:54:5f:5b:bb:cc:89
        Validity
            Not Before: Apr 30 17:38:14 2021 GMT
            Not After : Apr 29 17:38:14 2024 GMT
        Subject:
            countryName               = JA
            stateOrProvinceName       = Tokyo
            organizationName          = CaSample
            commonName                = ca-sample.com
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                70:05:DC:66:76:34:0B:A5:E8:B7:7C:AF:8F:5B:95:81:DE:F3:01:A2
            X509v3 Authority Key Identifier: 
                70:05:DC:66:76:34:0B:A5:E8:B7:7C:AF:8F:5B:95:81:DE:F3:01:A2
            X509v3 Basic Constraints: critical
                CA:TRUE
Certificate is to be certified until Apr 29 17:38:14 2024 GMT (1095 days)

Write out database with 1 new entries
Data Base Updated
==> 0
====
CA certificate is in ./demoCA/cacert.pem

CAの秘密鍵demoCA/private/cakey.pem に、CAの証明書は demoCA/cacert.pem にできます。

この証明書は自己署名になります。

% ../openssl/apps/openssl asn1parse -in demoCA/private/cakey.pem
    0:d=0  hl=4 l=1308 cons: SEQUENCE          
    4:d=1  hl=2 l=  78 cons: SEQUENCE          
    6:d=2  hl=2 l=   9 prim: OBJECT            :PBES2
   17:d=2  hl=2 l=  65 cons: SEQUENCE          
   19:d=3  hl=2 l=  41 cons: SEQUENCE          
   21:d=4  hl=2 l=   9 prim: OBJECT            :PBKDF2
   32:d=4  hl=2 l=  28 cons: SEQUENCE          
   34:d=5  hl=2 l=   8 prim: OCTET STRING      [HEX DUMP]:F7989A7B8D8C5F94
   44:d=5  hl=2 l=   2 prim: INTEGER           :0800
   48:d=5  hl=2 l=  12 cons: SEQUENCE          
   50:d=6  hl=2 l=   8 prim: OBJECT            :hmacWithSHA256
   60:d=6  hl=2 l=   0 prim: NULL              
   62:d=3  hl=2 l=  20 cons: SEQUENCE          
   64:d=4  hl=2 l=   8 prim: OBJECT            :des-ede3-cbc
   74:d=4  hl=2 l=   8 prim: OCTET STRING      [HEX DUMP]:3F41FB1FBA7D297F
   84:d=1  hl=4 l=1224 prim: OCTET STRING      [HEX DUMP]:2B22E6FBC....

% ../openssl/apps/openssl x509 -text -noout -in demoCA/cacert.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            5f:ea:3f:e3:bf:eb:68:e3:13:1c:b4:96:eb:ef:54:5f:5b:bb:cc:89
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = JA, ST = Tokyo, O = CaSample, CN = ca-sample.com
        Validity
            Not Before: Apr 30 17:38:14 2021 GMT
            Not After : Apr 29 17:38:14 2024 GMT
        Subject: C = JA, ST = Tokyo, O = CaSample, CN = ca-sample.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:9d:28:b4:02:86:ad:d0:0f:79:6b:2a:81:a3:3b:
                    fe:c9:97:80:fc:e1:e3:f7:8a:70:29:7b:55:99:e9:
                    e7:6e:a5:d8:45:4c:10:3c:71:90:b4:12:2e:0f:0d:
                    45:09:43:5a:09:3e:b8:73:32:43:52:64:2a:60:81:
                    46:0f:2b:ba:8c:d4:b3:1d:24:7a:f6:fa:9b:13:a6:
                    ce:f8:8e:45:54:64:39:48:43:18:c1:dd:ab:40:6e:
                    34:ab:39:1c:34:da:ae:06:82:5b:43:fc:7c:3d:99:
                    25:d7:96:11:94:3e:fa:52:42:7b:4c:eb:66:1a:c4:
                    ca:e8:d1:76:85:e5:94:0d:e8:e5:3e:84:17:9c:c8:
                    f3:96:91:1c:b1:38:e5:e6:d8:51:16:5f:ed:2c:38:
                    58:e9:d8:77:69:a8:ab:28:88:bc:c1:d7:36:8a:b5:
                    66:c5:1f:3f:93:94:48:de:a2:b0:90:e7:69:23:84:
                    66:e3:77:0b:ca:de:57:88:5c:b0:37:63:af:ee:51:
                    33:3e:ac:96:26:1c:58:2a:b7:91:35:85:34:cb:97:
                    6f:f4:6e:15:04:e7:36:03:8a:e8:86:c5:ae:cd:ea:
                    07:aa:48:c6:c5:2b:d6:6c:20:79:bf:5d:3d:b0:d6:
                    21:79:47:c6:6d:e6:89:c2:ec:20:72:46:13:52:11:
                    ae:bd
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                70:05:DC:66:76:34:0B:A5:E8:B7:7C:AF:8F:5B:95:81:DE:F3:01:A2
            X509v3 Authority Key Identifier: 
                70:05:DC:66:76:34:0B:A5:E8:B7:7C:AF:8F:5B:95:81:DE:F3:01:A2
            X509v3 Basic Constraints: critical
                CA:TRUE
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        7d:85:dd:92:00:7a:28:f5:d2:68:2f:b2:ad:67:4b:89:af:b8:
        e4:a1:c8:bb:9c:2b:f2:d5:0d:4f:d8:b0:41:4e:f0:9b:f4:12:
        76:3e:94:5c:ee:ff:97:eb:74:3c:c4:84:ba:bb:30:e4:94:a1:
        ed:ea:6e:45:cf:32:0b:ab:86:09:ae:44:3d:80:9d:e4:a7:60:
        87:fa:4a:d2:59:ca:d5:9a:60:9e:2c:37:7f:3d:b2:b3:e5:b2:
        ec:74:a2:7f:f5:7b:0f:c3:10:d5:19:c5:07:8e:3f:6c:ea:60:
        8b:b1:a1:55:3d:f0:58:46:0a:46:48:f3:92:7b:55:82:14:2c:
        ea:1d:7d:de:34:5a:df:2d:a6:b6:f4:5d:9c:d6:7b:16:fe:c7:
        3b:31:f0:d9:b7:6a:59:eb:39:d5:4e:e6:02:b5:52:bd:7c:7d:
        b5:37:de:81:17:5b:8b:23:c7:a9:6f:fe:13:d6:a2:03:cb:33:
        f6:50:d5:65:a1:6e:51:8a:71:e4:16:9c:e4:d7:0c:9b:e5:93:
        c7:84:68:ba:48:84:38:d4:12:64:5d:1f:ca:00:37:96:5d:a3:
        58:e4:f8:7f:79:dc:39:36:80:9e:76:e7:59:13:2a:85:c5:6d:
        b6:6f:f1:da:e0:e7:3c:d7:02:42:0f:e6:f9:9b:12:1a:50:00:
        64:ff:4b:98

中間CAの作成

CA.plとopenssl.cnfを中間CA用に書き換えたものを用意します。

% diff openssl.cnf openssl_intermidiate.cnf
76c76
< dir        = ./demoCA      # Where everything is kept
---
> dir        = ./intermidiateCA      # Where everything is kept
% diff CA.pl CA_intermidiate.pl
33c33
< my $CATOP = "./demoCA";
---
> my $CATOP = "./intermidiateCA";

ルートCAに署名をリクエストします。

% OPENSSL=../openssl/apps/openssl OPENSSL_CONFIG="-config ./openssl_intermidiate.cnf" ./CA_intermidiate.pl -newreq
Use of uninitialized value $1 in concatenation (.) or string at ./CA_intermidiate.pl line 145.
====
../openssl/apps/openssl req -config ./openssl_intermidiate.cnf -new  -keyout newkey.pem -out newreq.pem -days 365 
Ignoring -days without -x509; not generating a certificate
Generating a RSA private key
......+.......+......+..+.......+..+...+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*......+.....+...+...+...................+...........+...+......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+.....+...............+.+...........+...+.......+..+.......+...+..+....+..+.......+...+.....+....+........+..........+.....+.......+......+..+.+......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
....+.........+...+.....+............+.+..+....+.........+.........+..+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+.+...........+.+...+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.....+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Writing new private key to 'newkey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
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) [AU]:JA
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:Shibuya
Organization Name (eg, company) [Internet Widgits Pty Ltd]:IntermidiateCaSample
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:intermidiate.ca-sample.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
==> 0
====
Request is in newreq.pem, private key is in newkey.pem
% openssl req -text -in newreq.pem
Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = JA, ST = Tokyo, L = Shibuya, O = IntermidiateCaSample, CN = intermidiate.ca-sample.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:af:f7:18:b6:83:b2:55:97:49:a3:89:f0:38:74:
                    a0:4c:23:9f:8b:5c:14:33:30:ca:9b:12:d0:6f:e8:
                    3d:27:42:0a:72:2a:4d:29:00:4b:55:2d:3d:fc:3f:
                    aa:ad:8b:ce:90:02:f9:d4:e8:90:9b:bc:8d:6f:d0:
                    cc:e1:77:42:ce:79:a5:55:db:ad:56:e3:86:bb:ce:
                    4d:c1:39:cd:b6:8b:74:86:e3:14:0d:fb:3a:69:21:
                    22:17:cb:c1:47:15:f8:fb:67:70:50:7e:48:95:71:
                    50:b9:3b:dc:70:b9:a1:d5:c6:b1:93:b4:32:24:5b:
                    cf:46:e8:0b:09:7f:8d:3d:55:75:d8:9a:0c:9b:b9:
                    9c:be:74:9e:71:a7:d4:73:e0:0d:26:00:f1:69:fe:
                    c3:d0:17:81:b4:a2:e8:82:46:8c:5e:66:90:92:70:
                    ff:6d:c9:b0:a8:d1:21:dd:59:a3:e3:ad:64:5b:b4:
                    b3:3f:fb:3f:f6:3e:f5:b2:8c:36:0b:e4:44:63:d1:
                    28:45:69:8e:79:98:56:d5:75:27:70:d2:db:e7:fe:
                    67:fb:d4:ff:96:cb:fe:98:60:db:67:2e:b9:37:74:
                    53:c2:f9:b7:6f:0e:a1:bd:93:ba:30:bb:0b:61:7d:
                    da:85:a9:ed:4a:49:f2:67:93:65:c3:02:91:68:a4:
                    b8:21
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha256WithRSAEncryption
         37:d6:ab:3f:14:fe:21:4a:d3:41:07:a3:81:43:7a:d2:37:83:
         be:c6:72:b5:65:31:34:a7:1c:be:b5:7b:27:33:d7:5e:60:1b:
         6b:8e:22:20:b8:77:12:c9:8e:f8:fe:80:91:d0:68:97:84:04:
         a5:32:97:e8:9c:e9:ef:14:48:94:a4:ae:11:94:72:0f:61:5a:
         97:16:56:87:73:f2:ba:62:24:3f:62:b0:7c:fd:89:80:eb:50:
         bb:3c:58:23:b3:2a:31:bc:75:04:87:b7:e3:9f:63:77:53:86:
         f0:c6:bb:ba:e0:d2:ba:34:ba:aa:3d:66:a7:94:f4:e9:b7:54:
         0b:46:5e:00:67:6a:95:44:b1:e8:39:2c:db:9a:c3:ba:64:df:
         30:3f:a4:0b:1b:62:fb:02:50:84:f2:42:91:61:e3:8c:a2:f9:
         dd:6e:b0:aa:1e:d2:7d:8c:ac:bd:bc:9a:a9:67:30:b1:69:e3:
         6e:b6:65:9f:13:48:e2:e7:cb:73:e5:77:87:a4:71:e5:15:cf:
         7b:91:dc:0b:db:e8:0c:73:7a:ba:b7:b3:7b:f0:17:ca:88:4c:
         52:c8:8f:77:d1:2f:1a:60:5c:11:54:d7:ac:b9:b0:2d:70:db:
         db:db:9a:85:36:93:3b:93:80:f2:d9:97:28:cc:41:56:d5:0b:
         d3:db:94:25

できたCSRを元に、root CAが署名して証明書を作成します。

 % OPENSSL=../openssl/apps/openssl OPENSSL_CONFIG="-config ./openssl.cnf" ./CA.pl -signCA
====
../openssl/apps/openssl ca -config ./openssl.cnf -policy policy_anything -out newcert.pem -extensions v3_ca -infiles newreq.pem 
Using configuration from ./openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            5f:ea:3f:e3:bf:eb:68:e3:13:1c:b4:96:eb:ef:54:5f:5b:bb:cc:8a
        Validity
            Not Before: Apr 30 18:36:05 2021 GMT
            Not After : Apr 30 18:36:05 2022 GMT
        Subject:
            countryName               = JA
            stateOrProvinceName       = Tokyo
            localityName              = Shibuya
            organizationName          = IntermidiateCaSample
            commonName                = intermidiate.ca-sample.com
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                A9:C2:76:74:B1:39:64:63:66:CA:CB:32:7B:36:3D:B1:A5:56:1D:FA
            X509v3 Authority Key Identifier: 
                70:05:DC:66:76:34:0B:A5:E8:B7:7C:AF:8F:5B:95:81:DE:F3:01:A2
            X509v3 Basic Constraints: critical
                CA:TRUE
Certificate is to be certified until Apr 30 18:36:05 2022 GMT (365 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
==> 0
====
Signed CA certificate is in newcert.pem
% openssl x509 -text -noout -in newcert.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            5f:ea:3f:e3:bf:eb:68:e3:13:1c:b4:96:eb:ef:54:5f:5b:bb:cc:8a
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = JA, ST = Tokyo, O = CaSample, CN = ca-sample.com
        Validity
            Not Before: Apr 30 18:36:05 2021 GMT
            Not After : Apr 30 18:36:05 2022 GMT
        Subject: C = JA, ST = Tokyo, L = Shibuya, O = IntermidiateCaSample, CN = intermidiate.ca-sample.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:af:f7:18:b6:83:b2:55:97:49:a3:89:f0:38:74:
                    a0:4c:23:9f:8b:5c:14:33:30:ca:9b:12:d0:6f:e8:
                    3d:27:42:0a:72:2a:4d:29:00:4b:55:2d:3d:fc:3f:
                    aa:ad:8b:ce:90:02:f9:d4:e8:90:9b:bc:8d:6f:d0:
                    cc:e1:77:42:ce:79:a5:55:db:ad:56:e3:86:bb:ce:
                    4d:c1:39:cd:b6:8b:74:86:e3:14:0d:fb:3a:69:21:
                    22:17:cb:c1:47:15:f8:fb:67:70:50:7e:48:95:71:
                    50:b9:3b:dc:70:b9:a1:d5:c6:b1:93:b4:32:24:5b:
                    cf:46:e8:0b:09:7f:8d:3d:55:75:d8:9a:0c:9b:b9:
                    9c:be:74:9e:71:a7:d4:73:e0:0d:26:00:f1:69:fe:
                    c3:d0:17:81:b4:a2:e8:82:46:8c:5e:66:90:92:70:
                    ff:6d:c9:b0:a8:d1:21:dd:59:a3:e3:ad:64:5b:b4:
                    b3:3f:fb:3f:f6:3e:f5:b2:8c:36:0b:e4:44:63:d1:
                    28:45:69:8e:79:98:56:d5:75:27:70:d2:db:e7:fe:
                    67:fb:d4:ff:96:cb:fe:98:60:db:67:2e:b9:37:74:
                    53:c2:f9:b7:6f:0e:a1:bd:93:ba:30:bb:0b:61:7d:
                    da:85:a9:ed:4a:49:f2:67:93:65:c3:02:91:68:a4:
                    b8:21
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                A9:C2:76:74:B1:39:64:63:66:CA:CB:32:7B:36:3D:B1:A5:56:1D:FA
            X509v3 Authority Key Identifier: 
                keyid:70:05:DC:66:76:34:0B:A5:E8:B7:7C:AF:8F:5B:95:81:DE:F3:01:A2

            X509v3 Basic Constraints: critical
                CA:TRUE
    Signature Algorithm: sha256WithRSAEncryption
         25:b4:ef:8e:65:c7:6f:86:0c:91:63:f5:c4:3f:d0:3e:21:01:
         92:64:89:5b:71:d3:7d:fa:fd:64:eb:09:db:34:97:b1:6d:38:
         92:6f:8a:b4:c5:51:c0:85:c0:71:0d:ec:2b:71:50:77:6d:c0:
         f4:ca:3a:38:66:93:44:eb:aa:db:fa:07:22:14:5c:48:ab:18:
         b0:39:67:8a:80:59:b8:44:ac:84:3d:dd:aa:16:74:48:3d:aa:
         71:d2:37:fe:38:b6:9f:37:6c:fd:d4:79:ce:3d:0a:ca:31:68:
         4f:bb:19:c4:78:f0:32:1b:dd:5e:8f:42:e2:27:06:cb:b1:ff:
         c7:be:cf:3f:3b:84:d0:cd:c7:ba:e8:85:23:cc:1a:96:49:81:
         0d:7b:b6:1d:91:c7:58:b4:7d:2f:2f:f2:88:b0:ed:ad:29:36:
         14:43:1c:ee:c8:5c:37:29:df:dd:c4:38:e5:e0:70:5b:89:1b:
         a1:de:25:57:5e:c2:a6:fb:36:8a:e4:64:83:1e:e1:66:e3:a6:
         01:91:ac:08:89:95:e7:6c:4f:de:e1:f2:eb:f5:35:87:b2:42:
         c7:11:fa:f2:85:7e:30:db:52:71:45:3b:a0:5a:5f:15:6c:b4:
         98:81:f5:2c:ee:b5:fa:8a:63:fe:b9:8e:f9:ae:af:18:13:75:
         4d:b1:2e:4c

この証明書を元に中間CAを作ります。

% mkdir intermidiateCA
% mv new* intermidiateCA
% OPENSSL=../openssl/apps/openssl OPENSSL_CONFIG="-config ./openssl_intermidiate.cnf" ./CA_intermidiate.pl -newca
Directory ./intermidiateCA exists at ./CA_intermidiate.pl line 157.
CA certificate filename (or enter to create)
/Users/path/to/intermidiateCA/newcert.pem
 % tree intermidiateCA
intermidiateCA
├── cacert.pem
├── certs
├── crl
├── crlnumber
├── index.txt
├── newcert.pem
├── newcerts
├── newkey.pem
├── newreq.pem
└── private
    └── cakey.pem

# CAの作成時にうまく作成されないのでセットアップを自前でする
# serialの発行はもっとうまくできそう
cp intermidiateCA/newkey.pem intermidiateCA/private/cakey.pem 
echo 00 > ./intermidiateCA/serial

これで中間CAができました。

では実際に証明書を発行してみます。

% openssl genpkey -algorithm ed25519 -out server_key.pem 
% openssl req -new -out server_csr.pem -key server_key.pem

CSRの発行までは別でやってみて、署名した証明書を発行します。

% ../openssl/apps/openssl ca -config ./openssl_intermidiate.cnf -policy policy_anything -out server_certificate/server_crt.pem -extensions v3_ca -infiles server_certificate/server_csr.pem
Using configuration from ./openssl_intermidiate.cnf
Enter pass phrase for ./intermidiateCA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: May  3 18:56:55 2021 GMT
            Not After : May  3 18:56:55 2022 GMT
        Subject:
            countryName               = JA
            stateOrProvinceName       = Tokyo
            localityName              = Shibuya
            organizationName          = ServerCaSample
            commonName                = server.example.com
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Subject Key Identifier: 
                36:B5:66:C2:18:A9:43:92:A3:34:64:84:1C:0F:9A:19:3E:52:6A:85
            X509v3 Authority Key Identifier: 
                A9:C2:76:74:B1:39:64:63:66:CA:CB:32:7B:36:3D:B1:A5:56:1D:FA
Certificate is to be certified until May  3 18:56:55 2022 GMT (365 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

発行された証明書を検証してみます。

% openssl verify -CAfile demoCA/cacert.pem <(cat ./intermidiateCA/cacert.pem ./server_certificate/server_crt.pem)
#でもいいし
% cat intermidiateCA/cacert.pem server_certificate/server_crt.pem > crt.pem
% openssl verify -CAfile demoCA/cacert.pem crt.pem
crt.pem: OK

検証成功しました。

opensslの検証の実装

github.com

このあたりから読んでいけばよさそう

macでのopensslのビルド

./Configure darwin64-x86_64-cc shared enable-ec_nistp_64_gcc_128 no-ssl2 no-ssl3 no-comp --openssldir=~/path/to/dir
make depend
make

makeだけであればバイナリがopensslのapps配下に作られれるので、それを使いました。

NGだったパターン

gist:2f51fa1bfa33f25d9c667db9d83c2412 · GitHub

参考資料

qiita.com

www.openssl.org

ja.wikipedia.org

www.ipa.go.jp

pebble8888.hatenablog.com

typewriter.hatenablog.jp

9cubed.info

ssl.sakura.ad.jp

www.ykrods.net

qiita.com