One IT Thing

IT業界で飯を食う為の学習系雑記

security

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

投稿日:2019年5月12日 更新日:

すっかり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
-

執筆者:

関連記事

CentOSで暗号鍵用のパスワードを生成

そこそこ長くて文字種の入り混じった強度の高いものを自分で考えるのは面倒です。 暗号化処理を使う際に必要なパスワード文字列を、mkpasswdコマンドでいい感じに生成出来るようにしておきます。 目次1 …

pgcryptoの有効化と共通鍵暗号の動作確認

PostgreSQLで「pgcrypto」拡張機能を有効にすると、PostgreSQLに保存するデータを暗号化出来るようになります。 INSERTする際、共通鍵暗号はpgp_sym_encrypt関数 …

ブラウザでRSA暗号化したデータをサーバで復号する(Angular + JSEncrypt、Spring MVC)【前編】

セキュリティ的にクリティカルなデータをクライアントブラウザで暗号化保存するようにしてみます。 通信経路はHTTPSで暗号化されていてもスマホに重要なデータが平文で残っていたら珠に傷です。 目次1 環境 …

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

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

主要ブラウザに保存させたパスワードの確認方法を比較してみる(Firefoxをメインブラウザにしない理由)

アクセスしたサイトのパスワードをブラウザに覚えてもらったけどなんて入れたっけ? なんてこと結構あるんじゃないかと思います。 各種ブラウザとも覚えさせたパスワードは後から確認が出来るのでそれぞれの方法を …

 

shingo.7k24
 

東京在勤、職歴20年越え中年ITエンジニアです。まだ開発現場で頑張っています。

19歳(1996年)から書き始めた個人日記が5,000日を超え、残りの人生は発信をして行きたいと思い、令和元日からこのサイトを開始しました。勉強と試行錯誤をしながら、自分が経験したIT関連情報を投稿しています。

私と同じく、今後IT業界で生計を立てて行きたいと考えている方や、技術共有したいけどフリーランスで孤独、といった方と一緒に成長、知識共有して行けたら楽しいな、と思っています。