安全な通信を考える(共通鍵暗号/公開鍵暗号)

IPAが実施する情報処理資格の情報処理安全確保支援士やネットワークスペシャリスト試験。僕も受験しました。試験勉強しているなかで電子証明書とかPKIなど暗記してしまえばいいのかもしれないけれど、そもそも「なぜそんなことが必要なのか?」を理解するほうが頭に入ってきますので(僕の感覚でだけれど)、その考え方をまとめてみようと思います。実は、勉強していたときは「なるほど」と思い納得していたのだけれど時間が立つに連れ忘れてしまい、どこかでまとめておきたかったのでこのブログを機にまとめることにしました。3回にわけてまとめます。物語風です。

1回目:安全な通信を考える(共通鍵暗号/公開鍵暗号)
2回目:安全な通信を考える(ハッシュ関数/電子署名)
3回目:安全な通信を考える(電子証明書/PKI)

今回は、その1回目です。

■共通鍵暗号

安全な通信を行いたい場合、他の人が読めないように暗号化を行えば安心です。その暗号化の方式としてまず考え出されたのが「共通鍵暗号方式」です。これは共通鍵という鍵を使い暗号化と復号を行うものです。この共通鍵はAさん(送信者)とBさん(受信者)の双方が同じものを持っている必要があります。通信手順は以下となります。

  1. Aさんが共通鍵で送りたい情報を暗号化します。
  2. AさんがBさんにネットワークを介して、情報を送ります。
  3. Bさんが共通鍵で届いた情報を復号します。

共通鍵方式ではAさんもBさんも同じ鍵を使い暗号化と復号を行います。ポイントは「共通鍵はAさんとBさん以外に知られてはいけない」です。もし共通鍵が他者に漏れてしまった場合、盗聴されて暗号が解読されてしまうからです。

ただこの方式には根本的な問題があります(図1)。

図1

共通鍵をBさんに安全に渡す方法があるのであれば、共通鍵方式を使わずに、その方法でBさんに送りたい情報を送れば良いのだから。

■公開鍵暗号

そこで、共通鍵暗号方式とは別の方式が考え出されました。それが「公開鍵暗号方式」です。公開鍵方式では1対の鍵のペア(秘密鍵と公開鍵と呼ぶ)を生成し、AさんとBさんが別々の鍵を持ちます。通常は鍵のペアを生成したほうが秘密鍵を持ち、相手に公開鍵を渡します。Aさんが鍵を生成した場合はAさんが秘密鍵を持ち、Bさんに公開鍵を渡します。

この方式のポイントは、3つあります。

  • 秘密鍵は絶対に漏らしてはいけないが、公開鍵は他の人に渡ってもよい(むしろ公開する)。
  • 公開鍵で暗号化したものは秘密鍵で復号できる、秘密鍵で暗号化したものは公開鍵で復号できる。
  • 公開鍵を受け取ったほうから暗号文を送る。

共通鍵方式では共通鍵を渡す方法が問題でした。公開鍵方式では公開鍵を相手に渡してから(渡すときに他者に知られてもよい)通信を行います。鍵を生成し秘密鍵を持っているAさんが受信者、公開鍵を受け取ったBさんが送信者になり、通信手順は以下となります。

  1. Bさんが公開鍵で送りたい情報を暗号化します。
  2. BさんがAさんにネットワークを介して、情報を送ります。
  3. Aさんが秘密鍵で届いた情報を復号します。

公開鍵はBさん以外にも知られることになりますが、公開鍵から秘密鍵を生成することはできないので暗号化された内容を復号できるのは秘密鍵をもつAさんだけです。これで安全な通信ができるようになりました。

いや、、果たしてそうでしょうか(図2)?

図2

Aさんは公開鍵を公開してしまったのでBさんでない誰かがBさんを装い、Aさんに暗号文を送ってきたかもしれません。これでは安全な通信とは言えません。どうしたら良いでしょうか・・。

「安全な通信を考える(ハッシュ関数/電子署名)」に続く

Let’s EncryptでTLS化する(後編)

Let’s EncryptでTLS化する(前編)」からの続きです。

4.コンフィグファイルの確認

サーバ証明書の取得と同時に、certbot-autoはhttpd.confの書き換えとファイルの自動生成も行っています。

/etc/httpd/conf/httpd.conf ※書き換え
/etc/httpd/conf/httpd-le-ssl.conf ※自動生成
/etc/letsencrypt/options-ssl-apache.conf ※自動生成

httpd.confから、httpd-le-ssl.confを読み込んで(Includeして)いる。
httpd-le-ssl.confから、options-ssl-apache.confを読み込んで(Includeして)いる。

■ httpd.confの内容(変更前)※追記された箇所
==============================
<VirtualHost *:80>
 :
    RewriteEngine on
    RewriteCond ・・
    RewriteRule ・・
</VirtualHost>

<IfModule mod_ssl.c>
    NameVirtualHost *:443
</IfModule>
Include /etc/httpd/conf/httpd-le-ssl.conf
==============================
※certbot-autoを実行した際に「httpアクセスをhttpsにリダイレクトする」とすると「Rewrite・・」の記載が追記されています。

■ httpd-le-ssl.confの内容
==============================
<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerAdmin ・・
    DocumentRoot ・・
    ServerName ・・
    ErrorLog ・・
    CustomLog ・・
    <Directory "/var/www/html/・・">
        Options ・・
        
    </Directory>
SSLCertificateFile ・・
SSLCertificateKeyFile ・・
SSLCertificateChainFile ・・
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
==============================

■ options-ssl-apache.confの内容(変更前)
==============================
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite ・・
SSLHonorCipherOrder on
SSLOptions +StrictRequire
LogFormat ・・vhost_combined
LogFormat ・・vhost_common
==============================

Apacheのhttpd.conf、ssl.confの既存設定にもよりますが、このままではうまく行かない場合があります。
※僕の環境ではうまかいかなかったので、以下のような書き換えを行いました。ssl.confとhttpd-le-ssl.confの内容がダブってしまったようです。

5.httpd.confの書き換え

「NameVirtualHost *:443」は、let's Encryptがhttpd.conf に自動で記載済みでしたが、これはコメントアウトします。また、certbot-autoが自動生成したhttpd-le-ssl.confは使用しませんので、Include部分もコメントアウトします。

■ httpd.confの内容(変更後)
==============================
<VirtualHost *:80>
 :
    RewriteEngine on
    RewriteCond ・・
    RewriteRule ・・
</VirtualHost>

#<IfModule mod_ssl.c>
#    NameVirtualHost *:443
#</IfModule>
#Include /etc/httpd/conf/httpd-le-ssl.conf
==============================

6.ssl.confの書き換え

「NameVirtualHost *:443」の記載を追加します。
また、httpd-le-ssl.confの <VirtualHost *:443>…</VirtualHost> の部分を、/etc/httpd/conf.d/ssl.conf に転記します。その際、ssl.confにもともと記載があった <VirtualHost _default_:443>…</VirtualHost> の部分はコメントアウトします。

■ ssl.confの内容
==============================
LoadModule ssl_module modules/mod_ssl.so
Listen 443
NameVirtualHost *:443 (httpd.confから転記)
 :
<VirtualHost *:443> (httpd-le-ssl.confから転記)
    ServerAdmin ・・
    DocumentRoot ・・
    ServerName ・・
    ErrorLog ・・
    CustomLog ・・
    <Directory "/var/www/html/・・">
        Options ・・
        
    </Directory>
SSLCertificateFile ・・
SSLCertificateKeyFile ・・
SSLCertificateChainFile ・・
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
==============================

7.options-ssl-apache.confの書き換え

options-ssl-apache.confの中にあるLogFormatの記載をコメントアウトします(httpd.confにLogFormatの記載があるため)。

■ options-ssl-apache.confの内容(変更後)
==============================
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite ・・
SSLHonorCipherOrder on
SSLOptions +StrictRequire
#LogFormat ・・vhost_combined
#LogFormat ・・vhost_common
==============================

8.サイト内リンクの書き換え

サイト内に自サイトへのリンクがある場合はソースの「http://〜」を「https://〜」に書き換えます。
修正したコンフィグファイルのチェックを行い、Apacheの再起動をすればTLS化の対応は完了です。

# apachectl configtest (httpd.conf に間違いがないかチェックする)
# /etc/rc.d/init.d/httpd restart (Apacheの再起動)

ブラウザでアクセスしてみてください。URLの欄に鍵マークが表示されます。