20170624追記
RFC8188 として標準化されました
HTTPリクエスト・レスポンスのボディを暗号化する、「Content-Encoding: aes128gcm」を新しく標準化する「Encrypted Content-Encoding for HTTP」という仕様が議論されております。
提案自体は数年前に行われており、すでにWGドラフトになっています。
Encrypted Content-Encoding for HTTP
この仕様では、HTTPのボディをAEAD_AES_128_GCMで暗号化します。HTTPSと違って通信路だけでなく、アップロードファイル・ダウンロードファイル自体が暗号化されているため、ファイルが保存される場合も鍵を知っている人(ソフトウェア)のみがその内容を読むことができます。
仕様上では上記のような例があげられておりますが、IETFで同様に議論されているPush通知の標準プロトコル Web Push でこの仕様を使用します。「Message Encryption for Web Push」という仕様で、Content-Encoding: aes128gcmを使ってPush通知の暗号化プロトコルが実現されています。
暗号化概要
この仕様では、暗号化されたデータの他にも幾つかのパラメータをHTTPボディに含めて送信します。
具体的には下記のパラメータが暗号データ以外に送信されます
+-----------+--------+-----------+---------------+
| salt (16) | rs (4) | idlen (1) | keyid (idlen) |
+-----------+--------+-----------+---------------+
- salt: ソルト
- rs: レコードサイズ
- idlen: keyidの長さ
- keyid: keying materialの識別子
特徴として鍵交換の具体的方法は定義されておりません、別途別の手段で交換する必要があります。この仕様ではお互いにどのkeying materialを使用しているか識別するためのkeyidを通知するだけになります。
実際に暗号化に使用する鍵は、keying materialより導出されます。
鍵の導出
送信したパラメータと、keying materialより暗号化に用いる鍵を導出します
input keying material (IKM), pseudorandom key (PRK), content encryption key (CEK)
PRK = HMAC-SHA-256(salt, IKM)
cek_info = "Content-Encoding: aes128gcm" || 0x00
CEK = HMAC-SHA-256(PRK, cek_info || 0x01)
( || は結合)
ノンスの導出
同様にノンスも導出します
The record sequence number (SEQ)
nonce_info = "Content-Encoding: nonce" || 0x00
NONCE = HMAC-SHA-256(PRK, nonce_info || 0x01) XOR SEQ
レコードのシーケンス番号がつくことで、順番の入れ替えや欠落を検出できるようになっております。