俺々SSLサーバー証明書の作り方

ディスティングイッシュ名(Distinguished Name)を決める

属性名

略号

設定例

備考

国名(Country name)

C

JP

都道府県名(STate or province name)

ST

市区町村(Locality name)

L

組織名(Organization name)

O

部門名(Organization Unit name)

OU

コモンネーム(Common Name)

CN

*.ninth-nine.com

メールアドレス(emailAddress)

emailAddress

上記をまとめたのが下記の通りとなる。省略した項目は項目名から省略する(一切残さない)。

/C=JP/CN=*.ninth-nine.com

カスタムopenssl.cnfの準備

OS標準のopenssl.cnfは微妙に微妙なので、カスタマイズしたものを用意する。-configオプションにして指定する。 このファイルは典型的な ini ファイルなので、以下の構造を持つ。

[セクション名]
項目 = 値
 :

関連セクション・項目一覧

req セクション(必須)

項目名

意味

オプション

必須

備考

distinguished_name

セクション名

ディスティングイッシュ名セクションの指定

なし

必須

attributes

セクション名

属性セクションの指定

なし

オプション

通常不要

x509_extensions

セクション名

署名拡張セクションの指定

-extensions セクション名

オプション

req_extensions

セクション名

要求拡張セクションの指定

-reqexts セクション名

オプション

本件では不要

default_md

sha1 / sha256 等

署名アルゴリズムの指定

-sha / -sha256 等

オプション

指定が無い場合 -sha などに解釈

default_bits

数字

ビット数

なし

必須

何の?公開鍵暗号アルゴリズムによる

default_keyfile

パス名

秘密鍵のファイル名

-keyout パス名

オプション

指定が無い場合標準出力へ

RANDFILE

パス名

乱数シードのファイル名

-rand パス名

オプション

厳密には RANDFILE と -rand は違う

input_password

パスワード

指定された秘密鍵のパスワード

-passin パスワード

オプション

事前に秘密鍵は作らないので不要

output_password

パスワード

保存する秘密鍵のパスワード

-passout パスワード

オプション

パスワード保護しないので指定しない

encrypt_rsa_key

no

秘密鍵を3DES暗号化するかどうか

-nodes

オプション

encrypt_key と同義(compat)

encrypt_key

no

秘密鍵を3DES暗号化するかどうか

-nodes

オプション

3DES以外の選択肢無し

prompt

no

プロンプトを表示するかどうか

なし

オプション

string_mask

default

特定フィールドの文字列型で使用

なし

必須

utf8only

pkix

nombstr

WARNING

MASK:値

utf8

yes

UTF8 文字列を解釈する

-utf8

オプション

未指定の場合 ASCII

distinguished_name セクション(必須)

-subj ~オプションで必要な項目を指定するため、本セクションでの指定は無い。 ただし、セクション名自体は存在する必要がある。

x509_extensions セクション(オプション)

項目名

意味

備考

subjectKeyIdentifier

hash

authorityKeyIdentifier

keyid

keyid:always

issuer

basicConstraints

CA:FALSE

CA機能無し

CA:TRUE

CA機能有り

pathlen:0~

認証チェインの深さ(0 は子供のみ、1 は孫まで、2 ...)

nsCertType

client

クライアント証明書

server

サーバー証明書

email

メール証明書(S/MIME)

objsign

オブジェクト(コード)サイニング

sslCA

認証局

emailCA

メール認証局

objCA

オブジェクトサイニング認証局

keyUsage

digitalSignature

デジタル署名

nonRepudiation

否認不可

keyEncipherment

鍵交換

dataEncipherment

データ交換

keyAgreement

keyCertSign

cRLSign

encipherOnly

暗号化のみ

decipherOnly

複合化のみ

extendedKeyUsage

serverAuth

SSL/TLS Web Server Authentication.

clientAuth

SSL/TLS Web Client Authentication.

codeSigning

Code signing.

emailProtection

E-mail Protection (S/MIME).

timeStamping

Trusted Timestamping

msCodeInd

Microsoft Individual Code Signing (authenticode)

msCodeCom

Microsoft Commercial Code Signing (authenticode)

msCTLSign

Microsoft Trust List Signing

msSGC

Microsoft Server Gated Crypto

msEFS

Microsoft Encrypted File System

nsSGC

Netscape Server Gated Crypto

subjectAltName

DNS.n:ドメイン名

「拡張」で指定する値には「,」(カンマ)や「 」(空白)などを「直接」含めることができない。 下記の例のように間接的に指定する方法があるが、SANsの指定の場合、ドメイン名しか使わないので、セクション分けまでする必要は無い(どちらも同じ意味ではあるが)。

subjectAltName = DNS.1:*.ninth-nine.com, DNS.2:ninth-nine.com

subjectAltName = @altnames

[altnames]
DNS.1          = *.ninth-nine.com
DNS.2          = ninth-nine.com

設定ファイル(例)

[req]
distinguished_name = distinguished_name
x509_extensions    = x509_extensions
string_mask        = utf8only

[distinguished_name]

[x509_extensions]
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid,issuer
basicConstraints       = critical,CA:FALSE
nsCertType             = server
keyUsage               = digitalSignature, keyEncipherment
extendedKeyUsage       = serverAuth
nsComment              = "OpenSSL Generated Certificate"
subjectAltName         = DNS.1:*.ninth-nine.com, DNS.2:ninth-nine.com

自己署名証明書の作り方(RSA)

opensslコマンドのオプションは長いので複数行に分割している。実際の実行は、1行(改行無し)で記述すること。

openssl req
   -newkey rsa:2048
   -sha256
   -nodes
   -subj   "/C=JP/CN=*.ninth-nine.com"
   -out    "/ssl/*.ninth-nine.com/*.ninth-nine.com,rsa2048-sha256,201601-201912,0.crt"
   -keyout "/ssl/*.ninth-nine.com/*.ninth-nine.com,rsa2048-sha256,201601-201912,0.key"
   -x509
     -startdate "160101000000Z"
     -enddate   "191231235959Z"
   -config 設定ファイル

実行結果例(RSA)

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 13066507578601016103 (0xb5558f69d5768b27)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=JP, CN=*.ninth-nine.com
        Validity
            Not Before: Jan  1 00:00:00 2016 GMT
            Not After : Dec 31 23:59:59 2019 GMT
        Subject: C=JP, CN=*.ninth-nine.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:9e:c3:6e:6c:84:97:9a:17:d7:46:05:69:d2:7d:
                    65:0b:87:11:6e:65:af:dd:bf:b3:92:fe:df:32:b3:
                    84:c6:22:30:64:d0:90:17:93:6d:7e:77:4b:0a:86:
                    51:1b:c4:57:55:3b:e0:1c:63:e9:b3:d8:dd:bb:d8:
                    ae:58:3d:4b:34:98:4e:73:a5:9c:72:bb:18:51:df:
                    5b:f8:48:b3:3f:21:7f:73:9e:98:96:46:af:7d:29:
                    08:d5:8f:a8:0e:fc:18:6a:f1:09:4d:b6:36:17:76:
                    1f:0a:f4:9f:bb:b2:ea:50:9c:06:3c:30:58:76:b4:
                    27:e4:97:3c:bb:13:3b:24:d0:d1:a2:b5:08:29:ba:
                    da:f4:fa:fc:15:1e:73:11:1e:6b:9b:07:14:25:cd:
                    6b:6d:28:d0:45:85:63:69:3f:78:a7:bf:73:cd:98:
                    c1:c0:ba:79:a3:08:64:37:70:12:2e:11:b0:d7:34:
                    38:bd:cf:fc:d0:f5:f4:21:21:77:5b:36:d9:fd:cb:
                    ea:67:8c:7c:83:1e:62:6d:d1:50:e9:bb:70:c3:36:
                    46:c6:31:c0:a5:63:5a:92:4b:fe:3c:7f:de:39:ed:
                    08:ca:51:3a:f7:c7:b4:e1:b3:a5:d5:7f:b1:9c:27:
                    25:fc:6c:93:b6:84:4e:30:d8:eb:02:3a:24:c2:cc:
                    b9:25
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                67:E8:B1:6F:D0:19:1A:B7:39:45:4A:83:60:39:89:73:D6:D1:0D:FD
            X509v3 Authority Key Identifier:
                keyid:67:E8:B1:6F:D0:19:1A:B7:39:45:4A:83:60:39:89:73:D6:D1:0D:FD

            X509v3 Basic Constraints: critical
                CA:FALSE
            Netscape Cert Type:
                SSL Server
            X509v3 Key Usage:
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Alternative Name:
                DNS:*.ninth-nine.com, DNS:ninth-nine.com
    Signature Algorithm: sha256WithRSAEncryption
         06:f2:8e:7d:cd:78:37:b7:34:ca:fe:b2:47:13:a7:02:98:fe:
         78:8a:e3:02:d8:15:45:12:75:6b:30:7a:15:c1:0d:e1:22:55:
         56:e2:42:18:ca:d2:0d:c6:29:ac:b7:e3:e0:96:ca:58:5f:8a:
         06:de:bf:68:cb:d0:f2:a4:49:6f:33:9e:f3:0d:c9:4c:28:9a:
         59:d7:28:78:11:44:f5:b1:6f:b2:ad:00:d9:e3:53:42:f4:d5:
         5e:1a:43:43:2b:f5:f9:94:bb:d6:cd:36:a2:b8:71:b7:17:e9:
         0c:83:29:6f:d8:16:43:24:45:8d:44:a8:5c:97:27:63:36:1e:
         94:75:c1:3c:f0:d8:b4:9b:64:1f:cf:c8:f9:b7:e2:19:6a:ff:
         1b:f9:b5:75:82:08:3c:43:bf:23:28:1e:4b:11:ba:52:bb:ff:
         d9:62:3b:7b:06:ef:6c:c6:63:4f:a8:41:ae:17:87:74:93:28:
         68:94:0b:e7:01:79:43:43:cd:0a:ca:d4:84:94:bb:c2:89:3c:
         6e:35:97:97:05:72:55:c9:9f:07:c4:79:82:8e:c7:60:4b:52:
         a0:97:cd:22:6e:40:61:10:d4:84:14:d4:4d:24:c1:e7:25:08:
         4b:97:a9:d2:dd:50:62:c7:ac:24:5a:c3:41:ba:ee:72:e8:1d:
         6a:c5:1a:dc

自己署名証明書の作り方(ECDSA)

opensslコマンドのオプションは長いので複数行に分割している。実際の実行は、1行(改行無し)で記述すること。

openssl req
   -newkey ec:<(openssl ecparam -name prime256v1)
   -sha256
   -nodes
   -subj   "/C=JP/CN=*.ninth-nine.com"
   -out    "/ssl/*.ninth-nine.com/*.ninth-nine.com,prime256v1-sha256,201601-201912,0.crt"
   -keyout "/ssl/*.ninth-nine.com/*.ninth-nine.com,prime256v1-sha256,201601-201912,0.key"
   -x509
     -startdate "160101000000Z"
     -enddate   "191231235959Z"
   -config 設定ファイル

実行結果例(ECDSA)

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 15898934856903028020 (0xdca45d0424c7ed34)
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=JP, CN=*.ninth-nine.com
        Validity
            Not Before: Jan  1 00:00:00 2016 GMT
            Not After : Dec 31 23:59:59 2019 GMT
        Subject: C=JP, CN=*.ninth-nine.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:03:38:d7:62:50:7b:9b:0b:2d:9f:45:67:6d:8e:
                    af:e1:55:d6:1e:30:65:cd:97:0a:29:15:38:7a:2d:
                    fa:da:f1:48:e8:5b:b6:16:04:c7:6c:6f:0e:18:bb:
                    cf:e8:aa:82:66:66:89:79:bd:b8:94:e2:68:d1:43:
                    5b:1e:d4:49:dd
                ASN1 OID: prime256v1
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                32:98:80:2B:82:8F:F2:6F:4D:D5:D7:08:D9:0F:E5:CB:A0:E4:DA:99
            X509v3 Authority Key Identifier:
                keyid:32:98:80:2B:82:8F:F2:6F:4D:D5:D7:08:D9:0F:E5:CB:A0:E4:DA:99

            X509v3 Basic Constraints: critical
                CA:FALSE
            Netscape Cert Type:
                SSL Server
            X509v3 Key Usage:
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Alternative Name:
                DNS:*.ninth-nine.com, DNS:ninth-nine.com
    Signature Algorithm: ecdsa-with-SHA256
         30:45:02:21:00:c1:a5:7a:be:fb:cb:d7:ba:77:87:92:85:8e:
         bc:0a:f8:79:4e:30:f5:0c:2c:e8:54:c8:7c:4a:d5:8c:2d:38:
         9a:02:20:19:f8:83:b9:71:0e:bf:ba:9d:13:08:38:b6:93:78:
         f2:c2:0a:8d:75:58:fe:ae:38:94:cd:04:fa:01:fe:80:a1

Appendix

X509v3 Certificate Policies に関する考察

シマンテックの Global ID/Server ID EV SSL(要は Symantec Class 3 EV SSL CA - G3 ね)証明書を分析した結果についてメモっておく。

X509v3 Certificate Policies:
    Policy: 2.16.840.1.113733.1.7.23.6
      CPS: https://d.symcb.com/cps
      User Notice:
        Explicit Text: https://d.symcb.com/rpa

※なお、この設定を入れたところでEV SSL証明書にはならんので注意。DV SSL証明書扱いとなります。

先の設定ファイルの x509_extentions セクションに下記のように設定を追加してやると、上記と同じ結果が得られる。

[x509_extensions]
certificatePolicies    = @policies

[policies]
policyIdentifier       = 2.16.840.1.113733.1.7.23.6
CPS.1                  = https://d.symcb.com/cps
userNotice.1           = @notice

[notice]
explicitText           = https://d.symcb.com/rpa

パッチ

   1 Index: crypto/openssl/apps/req.c
   2 ===================================================================
   3 --- crypto/openssl/apps/req.c   (revision 298785)
   4 +++ crypto/openssl/apps/req.c   (working copy)
   5 @@ -126,6 +126,8 @@
   6   * -x509        - output a self signed X509 structure instead.
   7   * -asn1-kludge - output new certificate request in a format that some CA's
   8   *                require.  This format is wrong
   9 + * -startdate  - notBefore field
  10 + * -enddate    - notAfter field
  11   */
  12 
  13  static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *dn, int mutlirdn,
  14 @@ -179,6 +181,7 @@
  15      int nodes = 0, kludge = 0, newhdr = 0, subject = 0, pubkey = 0;
  16      char *infile, *outfile, *prog, *keyfile = NULL, *template =
  17          NULL, *keyout = NULL;
  18 +    char *startdate=NULL,*enddate=NULL;
  19  #ifndef OPENSSL_NO_ENGINE
  20      char *engine = NULL;
  21  #endif
  22 @@ -364,6 +367,14 @@
  23              if (--argc < 1)
  24                  goto bad;
  25              req_exts = *(++argv);
  26 +        } else if (strcmp(*argv,"-startdate") == 0) {
  27 +            if (--argc < 1)
  28 +                 goto bad;
  29 +            startdate= *(++argv);
  30 +        } else if (strcmp(*argv,"-enddate") == 0) {
  31 +            if (--argc < 1)
  32 +                 goto bad;
  33 +            enddate= *(++argv);
  34          } else if ((md_alg = EVP_get_digestbyname(&((*argv)[1]))) != NULL) {
  35              /* ok */
  36              digest = md_alg;
  37 @@ -428,6 +439,10 @@
  38          BIO_printf(bio_err,
  39                     " -days          number of days a certificate generated by -x509 is valid for.\n");
  40          BIO_printf(bio_err,
  41 +                   " -startdate     certificate validity notBefore - YYMMDDHHMMSSZ.\n");
  42 +        BIO_printf(bio_err,
  43 +                   " -enddate       certificate validity notAfter - YYMMDDHHMMSSZ.\n");
  44 +        BIO_printf(bio_err,
  45                     " -set_serial    serial number to use for a certificate generated by -x509.\n");
  46          BIO_printf(bio_err,
  47                     " -newhdr        output \"NEW\" in the header lines\n");
  48 @@ -796,13 +811,26 @@
  49                  if (!rand_serial(NULL, X509_get_serialNumber(x509ss)))
  50                      goto end;
  51              }
  52 -
  53 +            if (startdate == NULL) {
  54 +                if (!X509_gmtime_adj(X509_get_notBefore(x509ss), 0))
  55 +                    goto end;
  56 +            } else {
  57 +                if (!ASN1_UTCTIME_set_string(X509_get_notBefore(x509ss), startdate)) {
  58 +                    BIO_printf(bio_err, "start date is invalid, it should be YYMMDDHHMMSSZ\n");
  59 +                    goto end;
  60 +                }
  61 +            }
  62 +            if (enddate == NULL) {
  63 +                if (!X509_time_adj_ex(X509_get_notAfter(x509ss), days, 0, NULL))
  64 +                    goto end;
  65 +            } else {
  66 +                if (!ASN1_UTCTIME_set_string(X509_get_notAfter(x509ss), enddate)) {
  67 +                    BIO_printf(bio_err, "end date is invalid, it should be YYMMDDHHMMSSZ\n");
  68 +                    goto end;
  69 +                }
  70 +            }
  71              if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req)))
  72                  goto end;
  73 -            if (!X509_gmtime_adj(X509_get_notBefore(x509ss), 0))
  74 -                goto end;
  75 -            if (!X509_time_adj_ex(X509_get_notAfter(x509ss), days, 0, NULL))
  76 -                goto end;
  77              if (!X509_set_subject_name
  78                  (x509ss, X509_REQ_get_subject_name(req)))
  79                  goto end;

参考文献

certificate/俺々SSLサーバー証明書の作り方 (最終更新日時 2019-05-08 17:32:40 更新者 NorikatsuShigemura)