最近では外務省がパスポートに利用されている電子証明書の公開鍵を不開示としたことでも話題の電子証明書。
何年か前に自分でも拡張鍵用途を指定した電子証明書を作成したことがあった。最近、この電子証明書の有効期限が切れたために作成し直す必要があったのだが、作業時の手順などを記したメモがまともに残っておらず、2時間ほど時間を溶かしてしまったので、改めて記しておく。
もっとも、今回は電子証明書の有効期限を約100年に設定したので、同じプロジェクトでこの作業が必要になることはないはずなのだが……。
[鍵用途/拡張鍵用途について]
X.509形式の電子証明書には鍵用途 [Key Usage] というフィールドが含まれる。RFC5280によれば、このフィールドは以下の9つの値を複数取りうる。
- 電子署名(デジタル署名) [digitalSignature]
- 否認防止(否認不可) [nonRepudiation]
- 鍵暗号化 [keyEncipherment]
- データ暗号化 [dataEncipherment]
- 鍵交換 [keyAgreement]
- 電子証明書の検証 [keyCertSign]
- CRL(証明書失効リスト)の署名検証 [cRLSign]
- 鍵交換時のデータ暗号用 [encipherOnly]
- 鍵交換時のデータ複合用 [decipherOnly]
例えば、2019年4月26日時点の google.com のSSL証明書は、以下のように鍵用途には「デジタル証明書」のみが指定されている。
同様に、電子証明書には拡張鍵用途 [Extended Key Usage] というフィールドが含まれ、以下の6つの値を複数取りうる。
- サーバ認証 [serverAuth]
- クライアント認証 [clientAuth]
- コード署名 [codeSigning]
- 電子メール保護 [emailProtection]
- タイムスタンプ [timeStamping]
- OCSP(オンライン証明書失効確認プロトコル)署名 [OCSPSigning]
こちらも同じく google.com のSSL証明書で確認すると、以下のように「サーバ認証」が指定されている。
[拡張鍵用途ありの電子証明書作成手順]
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 []:
入力後の画面はこんな感じ。
いよいよ電子証明書ファイルを作成する。
$ 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ファイルから鍵を取り出す際に必要になるので忘れないように。
[まとめ]