security

HTTPS開発環境用、自己署名証明書の作成

投稿日:2019年5月12日

(2020/09/18追記)

mkcertを使ってより簡単に完璧なSSL証明書を作ることができました。
ささっと開発用のHTTPSサーバを作りたい時はmkcert使った方が良いですね。

以下投稿内容だとAndroid7以上のChromeで接続出来ません。


すっかりHTTPS必須の時代になり、それに併せてPWA関連、Payment Request API等、HTTPS環境下でないと機能しないAPIが出てきました。

開発を簡便にする為にlocalhostへのアクセスであれば動作する措置が取られていたりしますが、それでもスマホ実機からサーバにアクセスする際はURLがlocalhostでは無くなる為エラーになってしまいます。

インターネットに出ている機器ならLet’s Encryptを使って無料でサーバ証明書を作れてもWANやLANの中の開発用PCだと簡単にはいきません。

動かせなければコーディングも出来ないので、大多数のブラウザで許されるオレオレ証明書を作り、開発環境をSSL化していこうと思います。

作業環境

  • Windowsで作業実施。
  • Cygwinで入れたopensslコマンド(1.0.2系)使用。
  • C:\opensslディレクトリを作成し、作業ディレクトリとする。
  • 設定ファイル「openssl.cnf」原本を汚さない為、作業ディレクトリに同ファイルをコピーする。

備考

  • Chrome58以上に対応。CN(Common Name)の他、SAN(Subject Alternative Name)を設定(Chrome58以降、SANをサーバ所在として扱う為)
  • OpenSSLバージョンが1.0.2系であればOSは不問。
  • oepnsslの1.1.0系、3.0.0では未検証。(現時点の最新CentOS7.6を入れると1.0.2が入る。事実上1.0.2系がデフォルト。)
  • Androidは6以下のみ対応。Android7以上では手作業でインストールしたCA証明書は信頼されない為、HTTPSサーバ証明書として使用出来ない。

手順

作業ディレクトリを整える

  • C:\opensslディレクトリを作成。
  • opensslコマンドが1.0.2系であることを確認。
C:\openssl>openssl version
OpenSSL 1.0.2m  2 Nov 2017
  • Cygwin環境の/usr/ssl/openssl.cnfをC\:opensslにコピー。
  • 作業ディレクトリをカレントディレクトリに変更。
#dir     = ./demoCA     # Where everything is kept
dir     = ./     # Where everything is kept
  • CA署名時に使用されるシリアルナンバーファイルを作成。
touch ./index.txt
echo 00 > ./serial

CA(証明書認証局)を作成

CA秘密鍵を作成。(パスワードは任意に入力、備忘する)

C:\openssl>openssl genrsa -aes256 -out ./cakey.pem 2048
Generating RSA private key, 2048 bit long modulus
.......................................................................................................................................+++
.......................................................+++
e is 65537 (0x10001)
Enter pass phrase for ./cakey.pem: (パスワードを入力して備忘しておく)
Verifying - Enter pass phrase for ./cakey.pem:

CA証明書リクエストを作成。質問事項は任意に入力のこと。CNのみHTTPSサーバのIPにしておく。(クライアントOSにCA証明書をインストールした後分かり易い為)

C:\openssl>openssl req -new -key ./cakey.pem -config ./openssl.cnf -out cacert.csr
Enter pass phrase for ./cakey.pem: (CA秘密鍵のパスワードを入力)
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) []:Katsushika
Organization Name (eg, company) [Internet Widgits Pty Ltd]:適当な組織名
Organizational Unit Name (eg, section) []:適当な組織名
Common Name (e.g. server FQDN or YOUR name) []:192.168.0.5
Email Address []:適当なメールアドレス。届かなくてもOK

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:入力無し、エンター
An optional company name []:入力無し、エンター

同ディレクトリにv3_ca.txtを作成し、以下の内容を記述。(X509 v3拡張領域に以下内容を入れる為作成する)

basicConstraints = critical, CA:true
keyUsage = critical, cRLSign, keyCertSign
subjectKeyIdentifier=hash

CA証明書作成。

C:\openssl>openssl ca -in cacert.csr -selfsign -keyfile ./cakey.pem -notext -config ./openssl.cnf -outdir . -days 3650 -extfile v3_ca.txt -out cacert.pem
Using configuration from ./openssl.cnf
Enter pass phrase for ./cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: May 15 06:45:09 2019 GMT
            Not After : May 12 06:45:09 2029 GMT
        Subject:
            countryName               = JA
            stateOrProvinceName       = Tokyo
            organizationName          = 入力した組織名
            organizationalUnitName    = 入力した組織名
            commonName                = 192.168.0.5
            emailAddress              = 入力したメールアドレス
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Subject Key Identifier:
                DF:87:A9:7F:EC:64:13:B9:C0:DF:04:2B:E6:72:D4:C9:72:4F:74:E7
Certificate is to be certified until May 12 06:45:09 2029 GMT (3650 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

確認の為、出来たCA証明書をテキストダンプし、以下3点を確認。

openssl x509 -in cacert.pem -text

     (中略)

        X509v3 extensions:
            X509v3 Basic Constraints: critical       <-- 確認1.critical、CA:TRUEが入っていること
                CA:TRUE
            X509v3 Key Usage: critical               <-- 確認2.署名用途である左記の記述が入っていること
                Certificate Sign, CRL Sign
            X509v3 Subject Key Identifier:           <-- 確認3.署名するサーバ証明書との関連を示す左記IDが入っていること
                DF:87:A9:7F:EC:64:13:B9:C0:DF:04:2B:E6:72:D4:C9:72:4F:74:E7

サーバ証明書を作成

サーバ秘密鍵作成。

C:\openssl>openssl genrsa -aes256 -out ./server.key 2048
Generating RSA private key, 2048 bit long modulus
..........................................+++
...................................+++
e is 65537 (0x10001)
Enter pass phrase for ./server.key:パスワードを入力して備忘しておく
Verifying - Enter pass phrase for ./server.key:

サーバ証明書リクエスト作成。個人用途なのでCAと同じ内容で構いません。CN(Common Name)のみHTTPSサーバのIPに設定。(Chrome以外はCNがドメイン検証対象)

C:\openssl>openssl req -new -key ./server.key -config ./openssl.cnf -out server.csr
Enter pass phrase for ./server.key:
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) []:Katsushika
Organization Name (eg, company) [Internet Widgits Pty Ltd]:適当な組織名
Organizational Unit Name (eg, section) []:適当な組織名
Common Name (e.g. server FQDN or YOUR name) []:192.168.0.5
Email Address []:適当なメールアドレス。届かなくてもOK

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:入力無し、エンター
An optional company name []:入力無し、エンター

同ディレクトリにv3_server.txtを作成し、以下の内容を記述。(X509 v3拡張領域に以下内容を入れる為作成する)IP.1にはHTTPSサーバを起動する予定のPCのIPアドレスを設定する。

[SAN]
basicConstraints = CA:false
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
authorityKeyIdentifier=keyid,issuer

subjectAltName=@alt_names
basicConstraints=CA:FALSE
[alt_names]
DNS.1=localhost
IP.1=192.168.0.5  <-- HTTPSサーバを起動するPCのIPにする
IP.2=127.0.0.1

サーバ証明書作成。

C:\openssl>openssl ca -in server.csr -config openssl.cnf -keyfile ./cakey.pem -outdir . -extfile v3_server.txt -extensions SAN -out server.crt -days 3650
Using configuration from openssl.cnf
Enter pass phrase for ./cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 2 (0x2)
        Validity
            Not Before: May 15 06:47:36 2019 GMT
            Not After : May 12 06:47:36 2029 GMT
        Subject:
            countryName               = JA
            stateOrProvinceName       = Tokyo
            organizationName          = 入力した組織名
            organizationalUnitName    = 入力した組織名
            commonName                = 192.168.0.5
            emailAddress              = 入力したメールアドレス
        X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:localhost, IP Address:192.168.0.5, IP Address:127.0.0.1
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Authority Key Identifier:
                keyid:DF:87:A9:7F:EC:64:13:B9:C0:DF:04:2B:E6:72:D4:C9:72:4F:74:E7

Certificate is to be certified until May 12 06:47:36 2029 GMT (3650 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

上記コマンド後、以下のエラーが出る場合はindex.txtを削除、touch index.txtをやり直し、再度上記コマンド実行で成功する。

failed to update database
TXT_DB error number 2

確認の為、出来たサーバ証明書をテキストダンプし、以下5点を確認

openssl x509 -in server.crt -text

(中略)

    X509v3 extensions:
        X509v3 Subject Alternative Name:      <-- 確認1.SANで自分のHTTPSサーバIPが設定されていること
            DNS:localhost, IP Address:192.168.0.5, IP Address:127.0.0.1
        X509v3 Basic Constraints:             <-- 確認2.CA:FALSE
            CA:FALSE
        X509v3 Key Usage: critical            <-- 確認3.Digital Signature      
            Digital Signature, Key Encipherment
        X509v3 Extended Key Usage:            <-- 確認4.HTTPSサーバ用途
            TLS Web Server Authentication
        X509v3 Authority Key Identifier:      <-- 確認5.先のCAに署名されていること
            keyid:DF:87:A9:7F:EC:64:13:B9:C0:DF:04:2B:E6:72:D4:C9:72:4F:74:E7

パス無しサーバ秘密鍵作成。(パスが付いたままだとApache起動時にパスワードを聞かれてしまう、または起動に失敗する為)

openssl rsa -in ./server.key -out nopass_server.key

成果物

  1. CA秘密鍵:cakey.pem
  2. CA証明書:cacert.crt
  3. サーバ秘密鍵:nopass_server.key
  4. サーバ証明書:server.crt

が出来上がりました。これを使ってHTTPSサーバを立ち上げます。

  • 1は新しいサーバ証明書を作るまで置いておくだけ、取りあえず不使用。
  • 2はWebブラウザを起動するクライアント端末にインストール。
  • 3,4はApacheに設定。
SSLCertificateFile "C:\openssl/server.crt"
SSLCertificateKeyFile "C:\openssl/nopass_server.key"

CA証明書はWindows、Mac、Android、iOSそれぞれの方法でOSにインストールします。Windowsの場合はファイルをダブルクリックして「信頼されたルート証明機関」に入れれば完了です。

一回作っておくことでApacheに限らずNginxやNode.jsで起動するコマンドHTTPサーバをHTTPS化する為の作業コストが目減りしますね。

CA証明書をOSに入れたのにChromeで信頼されない時は「chrome://restart」でChromeを再起動してみてください。

-security
-

執筆者:

関連記事

mkcertとhttp-serverでHTTPS環境を作りAndroid(chrome)、iPhone(safari)から接続

簡単にパーフェクトなオレオレ証明書が作れるとgithub上で人気上昇中の「mkcert」。 GitHub  135 UsersFiloSottile/mkcerthttps://github …

SNS他Webサービスの情報流出、セキュリティ事故に巻き込まれたかどうか調べる

FaceBookやCapital Oneなど、サービスに登録されたユーザ情報が漏洩する事件が取り沙汰されています。 「もしかしたら自分が登録した情報も漏れてるかもしれない」 そう思って気になったら、セ …

開発用のRSA鍵ペア(バイナリ、テキスト)をopensslで作っておく

目次1 環境2 秘密鍵3 公開鍵4 まとめ 環境 CentOS7.6に付属のopenssl 1.0.2k。 $ cat /etc/redhat-release CentOS Linux release …

開発用のPKCS#12ファイルをOpenSSLで出来るだけ速く作る

「電子署名法」に則るにはセキュリティトークンが必要で、デジタル署名をちょっと試したいケースならPKCS#12が手っ取り早いです。 One IT Thing電子署名法で求められる「本人性」と「非改ざん性 …

Javascript(暗号化JSライブラリ「Forge」)とp12ファイルで署名値を作成、Javaで検証する

前回、送信データの改ざんを検知する為、簡易的なセキュリティトークンであるPKCS#12形式のファイルを作成しました。 One IT Thing  10 Pockets開発用のPKCS#12フ …

 

shingo.nakanishi
 

東京在勤、1977年生まれ、IT職歴2n年、生涯現役技術者を目指しています。健康第一。