2026年6月5日
2026年6月5日
TLS 1.3 と HTTP/2 の違い|役割の比較と両方を有効にする設定・確認方法
TLS 1.3 と HTTP/2 は「どちらを選ぶか」の関係ではありません。TLS 1.3 は通信を暗号化する層の規格、HTTP/2 はその上でWebページをやり取りする層の規格で、役割が違うため両方を同時に使うのが今の標準的な構成です。この記事では、二つの規格がそれぞれ何を改善するのかを比較したうえで、Nginx・Apache で両方を有効にする設定例と、実際に使われているかを確かめる方法までを解説します。
TLS 1.3 と HTTP/2 は担当する層が違う
ブラウザがHTTPSのサイトを開くとき、通信は大まかに次の順で積み重なっています。
- TCP でサーバーと接続する
- TLS で暗号化の取り決め(ハンドシェイク)を行う
- 暗号化された通路の中で HTTP のリクエストとレスポンスを送る
TLS 1.3 は2番目、HTTP/2 は3番目を担当します。TLS のバージョンを上げても HTTP の送り方は変わらず、HTTP/2 にしても暗号の強さは変わりません。「HTTP/2 にしたから安全になった」「TLS 1.3 にしたから並列読み込みが速くなった」という説明を見かけたら、層を取り違えていると考えてください。
| 観点 | TLS 1.3 | HTTP/2 |
|---|---|---|
| 担当 | 通信の暗号化・相手の認証 | HTTP メッセージの送り方 |
| 規格 | RFC 8446(2018年) | RFC 7540(2015年)、現在は RFC 9113 に改訂 |
| 主な改善 | ハンドシェイクの往復削減、古い暗号の廃止 | 1本の接続での多重化、ヘッダー圧縮 |
| 速くなる場面 | 接続を張る最初の瞬間 | 画像・CSS・JS など多数のファイルの取得 |
| 前提 | サーバーの TLS ライブラリが対応していること | ブラウザでは実質的に TLS 上でのみ利用 |
TLS 1.3 で変わったこと
ハンドシェイクが1往復になった
TLS 1.2 では暗号化の準備に通常2往復かかりましたが、TLS 1.3 は1往復で済みます。サーバーまでの距離が遠い(遅延が大きい)ほど差が出やすく、モバイル回線や海外からのアクセスで体感しやすい改善です。
再接続時には 0-RTT(初回データを即座に送る仕組み)も使えますが、0-RTT のデータは再送攻撃(リプレイ)を受ける可能性があります。ログインや決済のような副作用のあるリクエストには向かないため、よく分からない場合は無効のまま(多くのサーバーの既定値)にしておくのが無難です。
古く弱い仕組みが取り除かれた
TLS 1.3 では、RSA鍵交換、CBCモードの暗号、SHA-1 を使った署名、圧縮、再ネゴシエーションといった、過去に攻撃の対象になった仕組みが仕様から外されました。鍵交換は前方秘匿性(サーバーの秘密鍵が後で漏れても過去の通信を復号できない性質)を持つ方式に限られます。暗号スイートも少数に絞られ、設定ミスで弱い組み合わせを選んでしまう余地が小さくなっています。
HTTP/2 で変わったこと
1本の接続で多数のファイルを並行して運べる
HTTP/1.1 では1本の接続で同時に扱えるリクエストは基本的に1つで、ブラウザは複数の接続を張って並列化していました。HTTP/2 はデータを「ストリーム」という単位に分け、1本の接続の中で多数のリクエストを同時に流せます(多重化)。画像やCSS・JSが多いWordPressサイトでは、この恩恵が大きくなります。
ヘッダー圧縮とバイナリ形式
Cookie や User-Agent のように毎回ほぼ同じ内容を送るヘッダーは、HPACK という方式で圧縮されます。メッセージはテキストではなくバイナリのフレームでやり取りされるため、telnet で手打ちして確かめるような使い方はできなくなりました。
サーバープッシュは事実上使われなくなった
HTTP/2 にはサーバーが先回りしてファイルを送る「サーバープッシュ」がありましたが、効果が出にくく、主要ブラウザ(Chrome など)は対応を取りやめています。今から設定する場合はプッシュを前提にせず、必要なら <link rel="preload"> や 103 Early Hints を検討してください。
TCP の詰まりは残る
HTTP/2 でも下の層は TCP のままなので、パケットが1つ失われると同じ接続内の全ストリームが待たされます(TCP の Head-of-Line ブロッキング)。この問題を解消するために、QUIC(UDP ベース)の上で動く HTTP/3 が作られました。HTTP/3 は TLS 1.3 を QUIC の中に組み込んでいるので、ここでも「TLS 1.3 と HTTP のバージョンは別物だが組み合わせて使う」という関係は変わりません。
両者の関係:HTTP/2 は実質 TLS が前提
HTTP/2 の仕様自体には暗号化なしの方式(h2c)もありますが、主要ブラウザは h2c に対応しておらず、ブラウザ向けの HTTP/2 は TLS の上でのみ使われます。どちらのプロトコルを使うかは、TLS ハンドシェイクの中の ALPN という仕組みで決まります。サーバーが ALPN で h2 を返せば HTTP/2、返さなければ HTTP/1.1 になります。
また RFC 9113 では、HTTP/2 を TLS 上で使う場合は TLS 1.2 以上が求められます。つまり「TLS 1.2 以上で暗号化し、その上で HTTP/2 を話す」が最低ラインで、TLS 1.3 を加えるとハンドシェイクの速さと安全性がさらに改善される、という整理になります。
Nginx・Apache で両方を有効にする
設定を変える前に設定ファイルをバックアップし、可能ならステージング環境で試してください。TLS 1.3 を使うには、Web サーバーが OpenSSL 1.1.1 以降(または同等のライブラリ)でビルドされている必要があります。以下は一般的な書き方の例です(2026年10月現在)。お使いのバージョンの公式ドキュメントに合わせて調整してください。
Nginx の例
Nginx 1.25.1 以降は http2 on; で HTTP/2 を有効にします。それより前のバージョンでは listen 443 ssl http2; の書き方を使います。
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on; # 1.25.1 未満は listen 行に http2 を付ける
server_name www.example.com;
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3; # TLS 1.0 / 1.1 は無効
ssl_prefer_server_ciphers off;
}
sudo nginx -t && sudo systemctl reload nginx
Apache の例
Apache では mod_ssl と mod_http2 を有効にし、Protocols で h2 を許可します。mod_http2 は MPM が prefork だと利点が得にくいため、event(または worker)MPM と PHP-FPM の組み合わせが推奨されています。
<VirtualHost *:443>
ServerName www.example.com
Protocols h2 http/1.1
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/www.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.example.com/privkey.pem
SSLProtocol -all +TLSv1.2 +TLSv1.3
</VirtualHost>
sudo apachectl configtest && sudo systemctl reload apache2
TLS 1.2 を残しているのは、古い端末や一部の外部サービス(決済の通知、監視ツールなど)が TLS 1.3 に未対応のことがあるためです。TLS 1.3 のみに絞るのは、アクセス元を把握できてからにしてください。
実際に使われているかを確かめる
設定ファイルを書いただけでは、CDN やロードバランサーの手前で別のプロトコルに変わっていることがあります。外から見た結果を確認します。
# TLS 1.3 で接続できるか(Protocol 行に TLSv1.3 と出れば対応)
openssl s_client -connect www.example.com:443 -servername www.example.com -tls1_3 </dev/null 2>/dev/null | grep -E "Protocol|Cipher"
# ALPN で h2 が選ばれるか(ALPN protocol: h2 と出れば HTTP/2)
openssl s_client -connect www.example.com:443 -servername www.example.com -alpn h2 </dev/null 2>/dev/null | grep ALPN
# curl で使われた HTTP のバージョン(2 と表示されれば HTTP/2)
curl -s -o /dev/null -w '%{http_version}\n' --http2 https://www.example.com/
ブラウザでは、開発者ツールの Network タブで列に「Protocol」を追加すると、リクエストごとに h2 や h3 が表示されます。TLS のバージョンは、同じ開発者ツールのセキュリティ関連の表示や、リクエストの詳細から確認できます(表示場所はブラウザやバージョンで異なります)。
つまずきやすいのは次の点です。
- CDN 経由のサイト: ブラウザと CDN の間のプロトコルは CDN 側の設定で決まります。オリジンサーバーの設定を変えても、ブラウザから見た結果は変わりません。CDN とオリジンの間の TLS 設定も別途確認してください。
- h2 にならない: ALPN に対応していない古い OpenSSL でビルドされている、Apache が prefork のまま、
Protocolsが別の VirtualHost にしか書かれていない、といった原因がよくあります。 - 一部のクライアントだけ接続できない: TLS 1.2 を無効にした、または暗号スイートを絞りすぎた可能性があります。エラーログとアクセス元を確認してください。
WordPress サイトで期待できる効果
TLS 1.3 と HTTP/2 を有効にすると、接続の立ち上がりと多数の静的ファイルの取得が速くなりやすくなります。一方で、PHP の処理時間やデータベースの遅さ、重い画像、ブロッキングする JavaScript は改善しません。表示速度に課題がある場合は、プロトコルの設定に加えてキャッシュや画像の最適化も合わせて見直してください。
HTTP/1.1 時代の高速化手法として広まった「CSS・JS を1ファイルにまとめる」「ドメインを分けて並列数を増やす(ドメインシャーディング)」は、HTTP/2 では効果が薄いか、逆効果になることがあります。最適化プラグインの結合設定は、有効・無効の両方で実測して決めてください。
まとめ
- TLS 1.3 は暗号化の層、HTTP/2 は HTTP の送り方の層で、比べて選ぶものではなく組み合わせて使うもの
- TLS 1.3 はハンドシェイクの1往復化と古い暗号の廃止、HTTP/2 は多重化とヘッダー圧縮が主な改善点
- ブラウザ向けの HTTP/2 は TLS 上でのみ使われ、ALPN で
h2が選ばれるかが分かれ目 - 設定後は
openssl s_clientやcurl、開発者ツールで、外から見たプロトコルを確認する - CDN 経由の場合は CDN 側の設定が結果を左右する