OpenSSLを利用して拡張鍵用途を指定した電子証明書を作成する

f:id:kidani_a:20190426011001j:plain

最近では外務省がパスポートに利用されている電子証明書の公開鍵を不開示としたことでも話題の電子証明書

 

何年か前に自分でも拡張鍵用途を指定した電子証明書を作成したことがあった。最近、この電子証明書の有効期限が切れたために作成し直す必要があったのだが、作業時の手順などを記したメモがまともに残っておらず、2時間ほど時間を溶かしてしまったので、改めて記しておく。

 

もっとも、今回は電子証明書の有効期限を約100年に設定したので、同じプロジェクトでこの作業が必要になることはないはずなのだが……。

 

 

[鍵用途/拡張鍵用途について]

X.509形式電子証明書には鍵用途 [Key Usage] というフィールドが含まれる。RFC5280によれば、このフィールドは以下の9つの値を複数取りうる。

  • 電子署名(デジタル署名) [digitalSignature]
  • 否認防止(否認不可) [nonRepudiation]
  • 鍵暗号化 [keyEncipherment]
  • データ暗号化 [dataEncipherment]
  • 鍵交換 [keyAgreement]
  • 電子証明書の検証 [keyCertSign]
  • CRL(証明書失効リスト)の署名検証 [cRLSign]
  • 鍵交換時のデータ暗号用 [encipherOnly]
  • 鍵交換時のデータ複合用 [decipherOnly]

 

例えば、2019年4月26日時点の google.com のSSL証明書は、以下のように鍵用途には「デジタル証明書」のみが指定されている。

f:id:kidani_a:20190426022414p:plain

 

同様に、電子証明書には拡張鍵用途 [Extended Key Usage] というフィールドが含まれ、以下の6つの値を複数取りうる。

  • サーバ認証 [serverAuth]
  • クライアント認証 [clientAuth]
  • コード署名 [codeSigning]
  • 電子メール保護 [emailProtection]
  • タイムスタンプ [timeStamping]
  • OCSP(オンライン証明書失効確認プロトコル)署名 [OCSPSigning]

 

こちらも同じく google.com のSSL証明書で確認すると、以下のように「サーバ認証」が指定されている。

f:id:kidani_a:20190426023619p:plain

 

[拡張鍵用途ありの電子証明書作成手順]

OSはMacで、利用したOpenSSLのバージョンは以下の通り。

$ openssl version
LibreSSL 2.6.5

 

まずは秘密鍵を作成する。

$ openssl genrsa 2048 > private-key.pem
Generating RSA private key, 2048 bit long modulus
....................+++
....+++
e is 65537 (0x10001)

 

同改装に以下の内容の設定ファイル(cert.cnf)を作成しておく。今回は拡張鍵用途に「emailProtection」を設定している。

[ req ]
default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca
string_mask = utf8only

[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = AU
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Some-State
localityName = Locality Name (eg, city)
0.organizationName = Organization Name (eg, company)
0.organizationName_default = Internet Widgits Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 64

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = critical,emailProtection

[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical,CA:true

[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name

 

opensslコマンドを実行し、証明書署名要求ファイル(.csrファイル)を作成する。以下のように対話的に入力を求められるので、任意の内容を入力する。【】カッコ内が実際の入力内容であり、【】のない項目についてはエンターキーを押して入力を省略した。

$ openssl req -new -key private-key.pem -out cert.csr -config cert.cnf
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]:【JP】
State or Province Name (full name) [Some-State]:【Tokyo】
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:【KDNAKT】
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

入力後の画面はこんな感じ。

f:id:kidani_a:20190426025435p:plain

いよいよ電子証明書ファイルを作成する。

$ openssl x509 -req -days 3650 -in cert.csr -signkey private-key.pem -out cert.crt -extensions v3_req -extfile cert.cnf
Signature ok
subject=/C=JP/ST=Tokyo/O=Internet Widgits Pty Ltd/CN=KDNAKT
Getting Private key
$ ls
cert.cnf	cert.crt	cert.csr	private-key.pem

 

作成した証明書はopensslコマンドで中身を確認することができる。確かに設定ファイルで設定した「emailProtection」の値が拡張鍵用途に指定されていることが分かる。

$ openssl x509 -in cert.crt -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 13665903247015109418 (0xbda70a991d31632a)
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=JP, ST=Tokyo, O=Internet Widgits Pty Ltd, CN=KDNAKT
        Validity
            Not Before: Apr 25 17:55:53 2019 GMT
            Not After : Apr 22 17:55:53 2029 GMT
        Subject: C=JP, ST=Tokyo, O=Internet Widgits Pty Ltd, CN=KDNAKT
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:b8:f3:bd:ad:fc:fd:af:86:82:c3:9c:8f:76:19:
                    c7:5b:08:27:26:65:db:52:75:2a:89:09:74:a9:89:
                    9f:56:91:8c:c4:e2:31:8a:ac:51:af:04:e6:f0:48:
                    3e:fb:2c:f5:4f:34:c5:58:66:54:53:9d:7b:fa:e6:
                    8d:7c:46:c1:28:ce:f0:75:a3:42:54:68:40:84:be:
                    7f:d7:cf:28:73:bf:07:fb:c5:de:53:6c:db:b9:11:
                    c6:e6:53:67:d9:12:ce:35:fb:38:8c:b7:f5:bd:97:
                    77:90:67:71:2f:b3:37:2d:e3:0d:76:81:ed:82:72:
                    f6:ad:5e:d6:b9:c0:a4:e3:d4:4d:cd:92:d6:2a:1d:
                    65:5a:9b:e2:83:86:ee:9e:17:ad:a6:57:24:7e:ba:
                    cc:7e:88:6d:a1:6f:f8:d8:9c:e0:02:b1:65:24:41:
                    ab:18:87:05:3f:14:26:a2:57:7e:a5:16:55:20:97:
                    9e:db:37:20:89:5d:d0:b1:e6:66:b5:92:ec:ec:e5:
                    ac:02:12:00:45:9d:da:ad:ac:da:c3:57:62:58:25:
                    d6:98:98:2b:62:ed:90:99:10:45:03:66:15:a1:c4:
                    49:22:3a:99:d7:d1:2f:42:01:e4:db:62:cc:93:d6:
                    26:51:63:c4:a0:d6:ee:80:32:31:82:df:a4:61:74:
                    b4:cd
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Key Usage: 
                Digital Signature, Non Repudiation, Key Encipherment
            X509v3 Extended Key Usage: critical
                E-mail Protection
    Signature Algorithm: sha1WithRSAEncryption
         af:36:70:1f:4d:f0:46:69:a0:84:1d:f7:84:91:29:8c:06:9b:
         45:7f:e9:1f:b2:a4:23:10:9c:23:94:91:5e:22:4a:62:44:55:
         6a:25:99:6a:5d:c9:f3:af:e1:f6:3d:15:98:10:4e:e8:3e:2f:
         f6:f8:6d:a6:e4:e3:5b:89:f8:49:48:db:14:5b:07:73:f9:fe:
         49:38:36:0f:2a:81:41:92:f0:e6:48:ef:cc:c9:cb:d5:96:ad:
         17:1e:22:06:8a:6d:ce:1a:79:8b:34:84:96:9f:63:af:d9:ef:
         f2:d3:af:8f:47:e6:48:20:4d:82:60:5f:62:4a:e5:0a:ca:e3:
         4d:f1:6f:77:68:60:3a:34:4f:f9:e5:d7:12:06:c8:81:13:0c:
         d3:b1:ca:a3:46:c5:d0:49:e5:50:fb:5a:02:5b:98:bc:4c:87:
         d9:f1:4d:8a:34:07:fa:44:1e:18:88:82:13:81:e2:c6:0f:8a:
         77:1c:52:dd:1e:0b:51:f2:83:68:b4:73:33:13:1d:17:34:98:
         20:1e:e1:9c:3d:6f:62:ea:83:52:1e:e8:6a:94:af:dc:95:58:
         34:9f:f9:d2:d2:ca:ff:3c:2d:90:fd:26:9c:99:23:4a:47:01:
         a8:86:08:b4:90:91:3d:c9:a3:b1:ad:fc:e6:46:15:1b:10:cd:
         06:e8:fd:01
-----BEGIN CERTIFICATE-----
MIIDVzCCAj+gAwIBAgIJAL2nCpkdMWMqMA0GCSqGSIb3DQEBBQUAMFExCzAJBgNV
BAYTAkpQMQ4wDAYDVQQIDAVUb2t5bzEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
cyBQdHkgTHRkMQ8wDQYDVQQDDAZLRE5BS1QwHhcNMTkwNDI1MTc1NTUzWhcNMjkw
NDIyMTc1NTUzWjBRMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xITAfBgNV
BAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGS0ROQUtUMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuPO9rfz9r4aCw5yPdhnHWwgn
JmXbUnUqiQl0qYmfVpGMxOIxiqxRrwTm8Eg++yz1TzTFWGZUU517+uaNfEbBKM7w
daNCVGhAhL5/188oc78H+8XeU2zbuRHG5lNn2RLONfs4jLf1vZd3kGdxL7M3LeMN
doHtgnL2rV7WucCk49RNzZLWKh1lWpvig4bunhetplckfrrMfohtoW/42JzgArFl
JEGrGIcFPxQmold+pRZVIJee2zcgiV3QseZmtZLs7OWsAhIARZ3arazaw1diWCXW
mJgrYu2QmRBFA2YVocRJIjqZ19EvQgHk22LMk9YmUWPEoNbugDIxgt+kYXS0zQID
AQABozIwMDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAWBgNVHSUBAf8EDDAKBggr
BgEFBQcDBDANBgkqhkiG9w0BAQUFAAOCAQEArzZwH03wRmmghB33hJEpjAabRX/p
H7KkIxCcI5SRXiJKYkRVaiWZal3J86/h9j0VmBBO6D4v9vhtpuTjW4n4SUjbFFsH
c/n+STg2DyqBQZLw5kjvzMnL1ZatFx4iBoptzhp5izSElp9jr9nv8tOvj0fmSCBN
gmBfYkrlCsrjTfFvd2hgOjRP+eXXEgbIgRMM07HKo0bF0EnlUPtaAluYvEyH2fFN
ijQH+kQeGIiCE4Hixg+KdxxS3R4LUfKDaLRzMxMdFzSYIB7hnD1vYuqDUh7oapSv
3JVYNJ/50tLK/zwtkP0mnJkjSkcBqIYItJCRPcmjsa385kYVGxDNBuj9AQ==
-----END CERTIFICATE-----

 

[個人情報交換ファイルフォーマットへの変換]

ついでに、今回の作業では証明書ファイルと秘密鍵を個人情報交換ファイルフォーマット(.p12ファイル)に変換する必要があったので、その手順についても記載しておく。

$ openssl pkcs12 -export -in cert.crt -inkey private-key.pem -out cert.p12
Enter Export Password:(ここで任意のパスワードを入力する)
Verifying - Enter Export Password:(ここでパスワードを再入力する)

 

入力したパスワードは.p12ファイルから鍵を取り出す際に必要になるので忘れないように。

 

[まとめ]

  • 電子証明書を自作する場合は期限を気にしなくていいように設定すると楽そう
  • OpenSSLを利用して電子証明書に拡張鍵用途を指定することができる