20180824追記
Loading Signed Exchangesについて記事を書きました
Loading Signed Exchangesの仕様 (WebPackaging) - ASnoKaze blog
20180208追記
Bundled HTTP Exchangesについて記事を書きました
Bundled HTTP Exchanges とは (WebPackagingの議論より) - ASnoKaze blog
20180121追記
署名の仕組みとして Origin-Signed HTTP Exchanges を利用する方向のようです
HTTP/2 クロスオリジン サーバプッシュを可能にする提案仕様 - ASnoKaze blog
20171001追記
IETF99にてユースケースについてまずまとめるべき気というフィードバックが有り、それをうけて「Use Cases and Requirements for Web Packages」が提出されています
Webページを丸ごとパッケージングする、Web Packagingの仕様がIETFで提案されています
オフラインやローカル環境で共有出来るようになっており、主な特徴は
以上の点で、ZIPで固めて保存するのとはまったく違うことがわかるかと思います。
幾つかユースケースがありますが、主なものは以下のとおりです
- ローカル環境での共有。SDカードでの共有から、Physical Webと言ったその場でのBluetoothを用いた配信など
- Webのスナップショット保存。そのページをスナップショットとして保存する(署名無し)
- CDNでの配布。CDNや別の場所から再配布することが可能。この場合は署名をつけての配布が可能となる
フォーマット
webpackageのフォーマットは以下の通りである
webpackage = [
magic1: h'F0 9F 8C 90 F0 9F 93 A6', ; 🌐📦 in UTF-8.
section-offsets: { * (($section-name .within tstr) => offset) },
sections: ({ * $$section }) .within ({ * $section-name => any }),
length: uint, ; Total number of bytes in the package.
magic2: h'F0 9F 8C 90 F0 9F 93 A6', ; 🌐📦 in UTF-8.
]
- magic: 先頭と最後に挿入されるMagicコード。意味はない
- section-offsets: 各セクションへのオフセット値が与えられる。必須ではない
- sections: ここにManifestや実際のコンテンツが格納される(manifest, indexed-content)
- length: データ長
manifest及び、indexed-contentは以下で説明します。
manifest
sectionsに格納されるmanifestデータ。必須ではない。
日付、オリジン名、証明書、署名が格納される。また、アレば別オリジンのパッケージをサブパッケージとして読み込むことが出来る。
具体的には以下のパラメータです
- metadata: 日付、及びオリジンが記述される。また、あればサブパッケージの指定
- resource-hashes: 各リソースのハッシュ値
- signatures: 署名
- certificates: 証明書
例
"manifest": {
"manifest": {
"metadata": {
"date": 1(1494583200),
"origin": 32("https://example.com")
},
"resource-hashes": {
"sha384": [
h'3C3A03F7C3FC99494F6AAA25C3D11DA3C0D7097ABBF5A9476FB64741A769984E8B6801E71BB085E25D7134287B99BAAB',
...
]
}
},
"signatures": [
{
"keyIndex": 0,
"signature": h'3044022015B1C8D46E4C6588F73D9D894D05377F382C4BC56E7CDE41ACEC1D81BF1EBF7E02204B812DACD001E0FD4AF968CF28EC6152299483D6D14D5DBE23FC1284ABB7A359'
}
],
"certificates": [
DER(
Certificate:
...
Signature Algorithm: ecdsa-with-SHA256
Issuer: C=US, O=Honest Achmed's, CN=Honest Achmed's Test Intermediate CA
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
...
),
DER(
Certificate:
...
)
]
},
indexed-content
sectionsに格納される、indexed-content。ここにコンテンツの中身が格納される。
各リソースに対するHTTPリクエスト及びHTTPレスポンスが合わせて格納されており、ヘッダに関してはそれぞれHPACKでエンコードされている。
例
"indexed-content": [
[
[ hpack({
:method: GET
:scheme: https
:authority: example.com
:path: /index.html
}), 1]
[ hpack({
:method: GET
:scheme: https
:authority: example.com
:path: /otherPage.html
}), 121],
[ hpack({
:method: GET
:scheme: https
:authority: example.com
:path: /images/world.png
}), 243]
],
],
[
[ hpack({
:status: 200
content-type: text/html
date: Wed, 15 Nov 2016 06:25:24 GMT
expires: Thu, 01 Jan 2017 16:00:00 GMT
}),
'<body>\n <a href=\"otherPage.html\">Other page</a>\n</body>\n'
]
[ hpack({
:status: 200
content-type: text/html
date: Wed, 15 Nov 2016 06:25:24 GMT
expires: Thu, 01 Jan 2017 16:00:00 GMT
}),
'<body>\n Hello World! <img src=\"images/world.png\">\n</body>\n'
],
[ hpack({
:status: 200
content-type: image/png
date: Wed, 15 Nov 2016 06:25:24 GMT
expires: Thu, 01 Jan 2017 16:00:00 GMT
}),
'... binary png image ...'
]
]
]
セキュリティについて
オフラインの利用を想定しているため、証明書の失効確認については難しいところがあります。Webパッケージの利用者は正当性を確認する際は、オンライン時はOCSPを利用して失効確認が可能ですが、オフラインのときはブラウザによって判断されることになるでしょう(1週間だけ有効など)。
そこの部分については今後の議論になるかと思われます。