TLS 1.3 に備えて PHP 7.1 にアップグレードする


## 概要

2017年前半に TLS 1.3 の仕様が発行されます。TLS 1.3 では仕様の簡略化が進められ、速度が改善されるとともにプライバシーの保護の強化が図られています。Google が提唱する次世代プロトコルの QUIC は TLS 1.3 に対応し、2018年に仕様が発行される予定です。curl の開発者は QUIC 対応を表明しています。

2016年にリリースされた OpenSSL v1.1.1 は TLS 1.3 に部分的に対応し、2017年にリリース予定の v1.1.1 で完全に対応します。

OpenSSL 1.1 系には 1.0 系に対して後方互換性がない変更が多く含まれているため、PHP 7.1 は OpenSSL 1.1 系に対応しますが、PHP 5.6、7.0 は対応しない予定です。

今後5年10年後にTLS 1.3 を必須とするプロトコルが必要になったとき、もしくはブラウザーベンダーやクレジットカード決済サービスが TLS 1.2 のサポートを打ち切るとき、PHP 5 系および PHP 7.0 の打ち切りを検討する必要があります。

2017年は RHEL5/CentOS5 のサポートが打ち切られる年であり、日本国内において OS のアップグレードのための移行作業が注目されています。

### TLS 1.3 の変更内容

2016年12月19日の時点では TLS 1.3 の仕様は策定段階にあり、draft 18 が公開されています。おおまかな内容は [TLS 1.3 と 0-RTT のこわ〜い話](http://www.slideshare.net/kazuho/tls-13-0rtt) のスライドが参考になります。スライドの作者は HTTP/2 サーバーの h2o の開発者です。TLS ライブラリのサポート状況は Wikipedia の[比較記事](https://www.wikiwand.com/en/Comparison_of_TLS_implementations)にまとまっています。

### ブラウザーの TLS 1.3 サポート

2017年2月にリリース予定の Google Chrome 56、2017年3月にリリース予定の Firefox 52 はそれぞれ TLS 1.3 を利用できます。それ以前のバージョンでも設定を変更することで利用できます。

ブラウザーがサポートする TLS のバージョンは Wikipedia の[比較記事](https://en.wikipedia.org/wiki/Template:TLS/SSL_support_history_of_web_browsers)にまとまっています。

### 後方互換性のない OpenSSL 1.1 系への対応

OpenSSL 1.1.0 は OpenSSL 1.0.2 に対して後方互換性のない変更が含まれており、OS や言語やライブラリ開発者による移行作業が必要です。

#### OS・パッケージ管理ツール

2017年にリリースされる予定の Debian 9、Fedora 26 は OpenSSL 1.1.0 を搭載します。macOS のパッケージ管理ツールである homebrew の場合、OpenSSL 1.1 系のために従来とは別の formula ファイル (`openssl@1.1.rb`) を用意しました。

OpenSSL 1.1 は後方互換性のない変更が含まれていることとさまざまなライブラリが OpenSSL に依存していることから、OpenSSL のバージョンを上げる場合、OS のバージョンを上げるか、Docker コンテナーを検討する必要があります。

#### PHP Internals

OpenSSL 1.1.0 の対応は Jakub Zelenka (bukka) さんが作業を進めました ([OpenSSL ext status including port to OpenSSL 1.1](http://externals.io/thread/370))。 OpenSSL 1.1.0 は後方互換性のない変更が多いために PHP 7.0 にはバックポートしないとのことです。

また PHP 7.1 master でビルドできる OpenSSL の最小バージョンを v1.0.1 に引き上げることも[検討](http://externals.io/thread/122)されています。v1.0.1 は現時点で CentOS 7 や Debian 8 の標準パッケージで利用できるバージョンです。v1.0.1 は TLS 1.2 が利用できるものの ALPN には対応していません。Google Chrome は HTTP/2 通信の際に ALPN を必須とします。

### LibreSSL の TLS 1.3 対応状況

2016年の時点で LibreSSL を TLS 1.3 に対応させる動きは見られません。OpenSSL との互換 API に変更があるのか注目されます。Docker 社が開発を進めるコンテナ用 OS である Alpine Linux は v3.5 で LibreSSL に移行しました。

### TLS の最小バージョンの事例


#### QUIC

QUIC は Google が提唱する次世代プロトコルです。目標は UDP プロトコルの持つ速さと発展性に加えて、TCP プロトコルの持つ信頼性を兼ね備えることです ([GoogleのQUICプロトコル](http://postd.cc/googles-quic-protocol-moving-web-tcp-udp/))。QUIC の仕様は2017年に集中的に議論され、2018年に発行される予定です。TLS の最小バージョンは 1.3 を予定しています。

#### HTTP/2

HTTP/2 を利用する場合、TLS 1.2 とそれ以降のバージョンが要求されます。Google Chrome と HTTP/2 通信をする場合、ALPN が必須なので、OpenSSL の最小バージョンは 1.0.2 となります。CentOS 7 や Debian 8 などの主要な Linux ディストリビューションの場合、執筆時点で標準パッケージのバージョンが 1.0.1 であることから外部リポジトリや自前のビルドが必要です。

#### SNI（Server Name Indication)

SNI（Server Name Indication）は RFC 6066 で定義される TLS エクステンションです。1台のサーバー (IP アドレス)で複数ドメインの TLS 証明書を運用することができます。近年、SNI をサポートする HTTP サーバーとブラウザーが普及し、さくらのレンタルサーバなどの共有ホスティング業者や CDN 業者などがオプションサービスとして提供しています。

SNI に要求される TLS の最小バージョンは 1.0 です。OpenSSL は v0.9.8f とそれ以降のバージョンでサポートします。

#### ChaCha20-Poly1305

ChaCha20-Poly1305 は TLS 1.2 とそれ以降のバージョンで利用できる暗号方式です。ChaCha20 はストリーム暗号、Poly1305 はメッセージ認証符号です。

パフォーマンスにすぐれており、Google のウェブサービスと Google Chrome で採用されています。仕様は RFC 7905 です。OpenSSL 1.1.0 とそれ以降のバージョンでサポートされます。

#### クレジットカード決済

PCI DSS（Payment Card Industry Data Security Standard） v3.1 は2018年6月30日までに TLS の最小バージョンを 1.1 にすることを求めています ([SSL/TLS 1.0 はいつまでに無効化しなければならないか？](http://www.intellilink.co.jp/article/pcidss/18.html))。

PayPal は2017年6月30日以降は TLS 1.0、1.1 のサポートを打ち切ります。Stripe は2017年1月1日に TSL 1.0、3月1日に TLS 1.1 を打ち切ります。

TLS 1.0 のサポート打ち切りにより、Windows XP/Vista の IE、古いフィーチャーフォン、古い Android のブラウザーで決済ができなくなるので、EC サイトの売上や高齢者に影響があります ([日経の記事](http://itpro.nikkeibp.co.jp/atcl/column/14/346926/042200515/))。

#### SHA-2 証明書

主要なブラウザーやウェブサービスが SHA-1 証明書のサポートを打ち切り、SHA-2 証明書に移行しています。ハッシュアルゴリズム SHA-1 の安全性が低下したことと SHA-1 証明書を使って SHA-2 証明書を偽造できること、クラウドコンピューティングサービスによる証明書の偽造に必要なコストの低下が進んでいることが挙げられます ([GoogleがWebでのSHA-1の利用停止を急ぐ理由](http://postd.cc/why-google-is-hurrying-the-web-to-kill-sha-1/))。携帯キャリアは SHA-2 証明書に対応していない古いフィーチャーフォン (ガラパゴスケータイ) の一覧を公表しました。フィーチャーフォンの生産量が減って、店頭から在庫がなくなりつつあります。

#### ECC 証明書

ECC (楕円曲線暗号) 証明書は RSA 証明書よりも強い暗号強度とサーバーへの負荷軽減が期待できます。RFC 7027 で標準化され、TLS 1.0 とそれ以降のバージョンで利用できます。OpenSSL は 1.0.0 からデフォルトで ECC をサポートします。

#### ATS (App Transfer Security)

ATS (App Transport Security) は iOS および macOS の機能で、要件を満たさない HTTPS 通信を拒否します。App Store で公開されるアプリは ATS の対応が義務化される予定です。2016年の時点で TLS の最小バージョンは 1.2 です。くわしい要件は [Cocoa Keys](https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html) に記載されています。

#### Token Binding


Token Binding プロトコルではサーバーとクライアントのあいだの TLS 通信において、サーバーが検証可能な ID (Token Binding ID) を使ってクライアントを識別します。HTTP Cookie や OAuth 2.0 と組み合わせて使うことが想定されています。

日本語の解説は lepidum 社の[ブログ記事](http://www.lepidum.co.jp/blog/2016-12-20/tokbind/)をご参照ください。2016年の時点では RFC は草案 (draft) の状態です。Google の公開する [token_bind](https://github.com/google/token_bind) リポジトリによれば、OpenSSL 1.1.0 とそれ以降のバージョンが必要です。OpenSSL 1.1.0 の場合、パッチを適用する必要があります。

TLS 1.2 とそれ以下のバージョンを利用する場合、トリプルハンドシェイクの脆弱性への対策のために Extended Master Secret および Renegotiation Indication TLS エクステンションが利用できる必要があります (draft 7)。Extended Master Secret は OpenSSL 1.1.0 で導入されました。