自己署名証明書を作ってルート証明書として読み込んでみた

Apache

はじめに

自己署名証明書 (オレオレ証明書) を、ルート証明書としてインポートした場合の、ブラウザの挙動について調べた結果を報告します。

自己署名証明書によるSSL化では、ブラウザで自己署名を例外として受け入れても、アドレスバーに警告が残ります。この警告を消すために、自己署名証明書をルート証明書としてインポートする方法が、ネット上では紹介されています。これを試して見たところ、ブラウザによって挙動が異なることが分かりました。そこで主要なブラウザについて挙動を調べてみました。

最後に自己署名証明書の作成とインポートの手順についても記載しています。

ルート証明書としてインポートする手間をかけるのであれば、プライベート認証局を構築して、その認証局の証明書をルート証明書としてインポートするという選択肢も有ります。後述するように、自己署名証明書の場合は、Firefoxにルート証明書としてインポートできないという問題が有りますが、プライベート認証局の証明書の場合は、Firefoxにも問題なくインポートできます。また複数のサーバーがある場合も、ルート証明書のインポートは一度で済みます。

プライベート認証局によるサーバー証明書の発行
プライベート認証局を構築して、Webサーバー向けのサーバー証明書を発行する手順について紹介します。認証局の証明書をWebブラウザやOSの証明書ストアに読み込むことで、自己署名証明書を使ったサーバーに、警告なしにアクセスすることができます。

テストケース

以下の4つのケースでテストしました。従来通りブラウザで例外として受け入れた場合 (ケース1, 2)、ルート証明書としてインポートした場合 (ケース3, 4) をテストしています。

ケース SAN 証明書の処理
1 例外受入
2 例外受入
3 インポート
4 インポート
  • SAN – subjectAltNameにサーバーのFQDNを指定する
    SANは証明書に含めることのできるフィールドのひとつです。Chromeはこれを設定しないとエラーになるとの記述があったので試してみました。
  • 例外受入 – ブラウザの警告画面で、例外を受け入れる (警告を無視してアクセス)
  • インポート – ルート証明書としてインポートする

使用ソフトウェア

テストに使用したブラウザとApacheのバージョンです。Mac OSとWindows 11でテストしています。

Mac OS (Ventura)

  • Safari 16.4
  • Chrome 112.0.5615.45
  • Edge 110.0.1661.62
  • Firefox 111.0.1

Windows 11 Pro

  • Chrome 111.0.5563.147
  • Edge 111.0.1661.62
  • Firefox 111.0.1

Web Server

  • Apache 2.4

結果

テスト結果を下表に示します。MacとWindows環境で違いはなかったので、まとめてあります。

  • ルート証明書としてインポートする場合は、SAN付きで証明書を作成する必要があります。
  • ただしFirefoxにはルート証明書としてインポートできません。
ケース1 ケース2 ケース3 ケース4
Safari 警告 -> ◯ (*1) 警告 -> ○
Chrome 警告 -> 保護されていない通信 (*2) 警告 -> 保護されていない通信 (*2) 警告 -> 保護されていない通信 (*3)
Edge 警告 -> セキュリティ保護なし (*2) 警告 -> セキュリティ保護なし (*2) 警告 -> セキュリティ保護なし (*3)
FireFox 警告 -> 安全でない接続 (*4) 警告 -> 安全でない接続 (*4) X (*5) X (*5)
備考 例外受入
SAN無
例外受入
SAN有
インポート
SAN無
インポート
SAN有

*1 – 例外を受け入れた後は警告を出ない。

*2 – 例外を受け入れた後もアドレスバーに警告が出される。
エラーコード: ERR_CERT_AUTHORITY_INVALID

*3 – 例外を受け入れた後もアドレスバーに警告が出される。
エラーコード: ERR_CERT_COMMON_NAME_INVALID

*4 – 例外を受け入れた後もアドレスバーに警告が出される。
エラーコード: MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT

*5 – 「認証局の証明書でないため、認証局の一覧には追加できません。」と表示されて、ルート証明書としてインポートできない。

考察

ブラウザごとの挙動

Safari

SANの有無に関わらず、ルート証明書としてインポートすることで警告を消すことができます。

例外として受け入れた場合も、他のブラウザのような警告は出しません。従ってあえてルート証明書としてインポートする必要はなさそうです。ただし一度例外を受け入れると、削除する方法が不明です。(筆者が見落としているだけかも知れません。間違って受け入れたときなど取り消せないと困るのですが …)

Chrome, Edge

SANを含めて証明書を作成し、ルート証明書としてインポートすることで、警告を消すことができます。

※ ChromeとEdgeは、Chromiumベースなので、基本的に同じ挙動のようです。

Firefox

ルート証明書としてはインポートできませんでした。Safari, Chrome, EdgeがOSの証明書ストアを使っているのに対して、Firefoxは自前の証明書ストアを持っていて、その部分で他のブラウザとは動作が異なるようです。

Windows vs. Mac

WindowsとMac OSで挙動に違いはありません。

例外の受け入れと削除 (解除) について

以下は証明書を「例外として受け入れた場合」の動作についての考察です。

  • 例外を受け入れると、Webブラウザの持つ (OSの証明書ストアでない) ローカルの証明書ストアに登録されます。(Safari, Chrome, Edgeの持つ証明書ストアは開示されていません。)
  • クライアントのOSを再起動しても例外は削除されません。
  • 受け入れた例外の削除方法は、
    • Safariの場合、例外をブラウザ側で削除する方法は不明です。
    • Firefoxの場合、アドレスバーで「安全でない接続」をクリックし、「例外から削除」をクリックすると証明書ストアが開き例外を削除できます。
    • Chromeの場合、アドレスバーで「保護されていない通信」をクリックし、「警告をオンにする」をクリックすると例外が削除されます。また「警告をオンにする」が表示されない場合は、アドレスバーをクリックした時点で例外が削除されます。
    • Edgeの場合、アドレスバーで「セキュリティ保護なし」をクリックし、「警告を有効にする」をクリックすると例外が削除されます。また「警告を有効にする」が表示されない場合は、アドレスバーをクリックした時点で例外が削除されます。
    • Chrome, Edgeで「警告をオンにする」「警告を有効にする」が表示される場合とされない場合がありますが、何が機序になっているのか不明です。

ブラウザでのチェックについて

Chrome, Edgeの場合は、サーバー証明書に対して次のようなチェックがされているようです。

  1. 第三者による署名がされているかどうか
  2. サーバーのアドレスが正しく設定されているか

自己署名証明書を持つサーバーにアクセスした場合は、まず#1のチェックで警告が出ます。

ルート証明書としてインポートした場合は、#1のチェックはパスするようです。しかし#2のチェックでSANが設定されていないと警告が出るようです。

自己署名証明書の作成

SAN有りの場合

自己署名証明書をSAN有りで作成する方法を説明します。

まず秘密鍵 (web-server.key) を作成します。

openssl genpkey -out web-server.key -algorithm RSA -pkeyopt rsa_keygen_bits:2048

次に署名要求 (web-server.csr) を作成します。署名要求にはsubjectAltNameを含めています。example.comは、証明書発行対象のサーバーのFQDN (Fully Qualified Domain Name) で適宜置き換えてください。

openssl req -new -key web-server.key -out web-server.csr -addext "subjectAltName=DNS:example.com"

DNS名ではなくIPアドレスを指定する場合は、次のように指定します。

subjectAltName=IP:aaa.bbb.ccc.ddd

下記の項目について質問されるので、適宜指定してください。

Country Name (2 letter code) [AU]: JP
State or Province Name (full name) [Some-State]: Tokyo
Locality Name (e.g. city) []: Chiyoda
Organization Name (eg. company) [Internet Widgits Pty Ltd]: Hoge LLC
Organiztion Unit Name (eg. section) []: Home
Common Name (e.g. server FQDN or YOUR name) []: example.com
Email Address [];

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

必須項目は、Country Name, Organization Name, Common Nameです。

Common Nameは、Webブラウザに入力されたアドレスと比較されます。WebサーバーがFQDNを持っている場合は、それを指定します。IPアドレスしか持たない場合は、IPアドレスを指定します。

A challenge passwordは設定しないでください。設定した場合は、Webサーバーの起動時に、パスワードの入力が必要になります。

署名要求に署名して、自己署名証明書 (web-server.crt) を作成します。

openssl x509 -in web-server.csr -out web-server.crt -req -signkey web-server.key -days 365 -copy_extensions copy

SAN無しの場合

自己署名証明書をSAN無しで作成する方法を説明します。

まず秘密鍵 (web-server.key) を作成します。

openssl genpkey -out web-server.key -algorithm RSA -pkeyopt rsa_keygen_bits:2048

次に署名要求 (web-server.csr) を作成します。

openssl req -new -key web-server.key -out web-server.csr

下記の項目について質問されるので、適宜指定してください。

Country Name (2 letter code) [AU]: JP
State or Province Name (full name) [Some-State]: Tokyo
Locality Name (e.g. city) []: Chiyoda
Organization Name (eg. company) [Internet Widgits Pty Ltd]: Hoge LLC
Organiztion Unit Name (eg. section) []: Home
Common Name (e.g. server FQDN or YOUR name) []: example.com
Email Address [];

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

必須項目は、Country Name, Organization Name, Common Nameです。

Common Nameは、Webブラウザに入力されたアドレスと比較されます。WebサーバーがFQDNを持っている場合は、それを指定します。IPアドレスしか持たない場合は、IPアドレスを指定します。

A challenge passwordは設定しないでください。設定した場合は、Webサーバーの起動時に、パスワードの入力が必要になります。

署名要求に自己署名して、自己署名証明書 (web-server.crt) を作成します。

openssl x509 -in web-server.csr -out web-server.crt -req -signkey web-server.key -days 365

自己署名証明書のブラウザへのインポート

Mac OSの場合

筆者の手元にあるMac OS (Ventura 13.3) の環境では次の通りです。

Safari / Chrome / Edge

Safari、ChromeとEdgeは、OSのキーチェーンに格納された証明書を参照しています。このためキーチェーンアクセスを起動して、証明書を読み込みます。

デフォルトキーチェーン > ログイン > 証明書 > 新規のキーチェーン項目を作成します。

筆者の環境 (Ventura 13.2.1) では、当初は新規のキーチェーン項目を作成します。のアイコンが、無効化されたままでした。そこでメニューで、iCloud > ログイン と切り替えると、アイコンが有効になりました。操作によって再現したりしなかったりなので、筆者の環境固有の問題かも知れませんが、もし同じ問題に当たったら、上記を試してみてください。

アイコンをクリックすると、ファイル選択のダイアローグが表示されるので、先ほど作成したweb-server.crtファイルを開きます。

証明書リストに、example.com (証明書の作成時に指定したCNが証明書名として使われる) が追加されます。この段階ではリスト上のアイコンに⚠️がついていて、説明欄には「自己署名ルート証明書」の表示はあるものの、「この証明書は第三者によって信頼されていません」と表示されています。

ダブルクリックして証明書を開きます。> 信頼 というセクションが表示されているので開きます。

この証明書を使って信頼すべき対象の一覧が表示されます。ここでSSLのプルダウンから常に信頼を選択します。

ダイアローグを閉じると、変更に対するパスワードを要求されるので入力します。

リスト表示に戻ると先ほどの⚠️が消えています。また説明欄には「この証明書はこのアカウントにとって信頼されているものとして指定されています」と表示されています。

Webブラウザから証明書を読み込むこともできます。この場合もキーチェーンアクセスが起動されます。

Webブラウザのメニュー > 設定 > プライバシーとセキュリティ > 証明書 > デバイス証明書の管理

Firefox

Firefoxには自己署名証明書はインポートできません。

Windowsの場合

Chrome / Edge

ChromeとEdgeは、OSの証明書ストアに格納された証明書を参照しています。このためWindowsの管理コンソールから、証明書を読み込みます。

タスクバーで証明書の管理コンソールを検索します。

certmgr.msc

検索結果に次のように表示されたら、「開く」をクリックして起動します。

管理コンソールが起動したら、証明書をインポートします。ファイル選択のダイアローグが表示されるので、先ほど作成したweb-server.crtファイルを開きます。

信頼されたルート証明機関 > 証明書 > すべてのタスク > インポート

証明書のインポートウィザードが起動します。途中選択を求められますが、次の項目を選択します。

保存場所: 現在のユーザー

証明書ストア: 証明書をすべて次のストアに配置する > 信頼されたルート証明機関

最後にセキュリティ警告で、証明書の発行者が確認できない旨のメッセージが出ます。これは自己署名証明書であるためです。自分で作成した証明書なので「はい」をクリックして、証明書を受け入れます。

Firefox

Firefoxには自己署名証明書はインポートできません。

Webサーバーへの組み込み

Apacheに組み込んでHTTPS化した例について次の記事で紹介しています。

Apacheをプライベート認証局やオレオレ証明書でHTTPS化
Apacheで構築したWebサーバーのHTTPS化について紹介します。サーバー証明書には、プライベート認証局で署名した証明書、または自己署名した証明書を使っています。

変更履歴

日時内容
2024/03/25インポート手順を記載 (元は別記事へのリンク)
表記を見直し
2023/12/18表記・文言を見直し
2023/05/09テストの実行手順を追記
2023/04/07初版リリース

コメント

タイトルとURLをコピーしました