非公式翻訳 (Unofficial translation). これは WACZ Signing and Verification 0.1.0 仕様の有志による日本語訳です。 正典は英語原典 specs.webrecorder.net/wacz-auth/0.1.0 。 原著作: Webrecorder, CC BY 4.0。 本訳は原文を翻訳・改変したもので、Webrecorder の公認・推奨を示すものではありません。

# Introduction この文書は、パッケージの作成者を暗号学的に証明できる署名付き WACZ パッケージを 作成するための提案の作業草案 (working draft) である。 ## Motivation この仕様の目的は、WACZ にまとめられたウェブアーカイブの信頼性を高めるための 任意 (optional) の仕組みを提供することである。 WACZ 形式は、可搬なウェブアーカイブを作成し、それを任意のオンラインネットワークを 通じて分散的に配布する手段を提供する。 ウェブアーカイブへの信頼を高めるには、そのウェブアーカイブを誰がいつ作成したかに ついて、一定の性質を保証することが必要になる。 ## Proof of Authenticity ウェブアーカイブの真正性 (authenticity) を証明するのは難しい。理想的には、真正性の 証明は「あるウェブサーバが特定の時点に特定の URL を配信した」ことを保証できるはず である。しかし残念ながら、既存のウェブ標準では現時点でこれは不可能である。TLS で さえ「否認防止 (non-repudiation)」を提供しないからである。 [signed exchanges](https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html) のように、後から検証できる形でウェブサーバがコンテンツを配信する新しい方法の提案も 存在する。しかしこれには、HTTPS サーバが新しいプロトコルと形式に対応する必要がある。 ウェブアーカイブは、自身が関与した HTTP 通信を記録できる HTTP クライアントであれば どれでも作成できる。この仕様の目標は、ウェブアーカイブを作成して WACZ 形式で保存 するクライアントが、あわせて認証情報を付加できるようにする方法を提供することである。 この提案が認証の仕組みを提供する対象は次のとおり: - ウェブアーカイブの作成者の身元 (identity) - ウェブアーカイブが作成された時刻のタイムスタンプ この方式は、クライアントと、場合によってはウェブアーカイブに署名する信頼できる 第三者の「観測者 (observer)」とを信頼することを前提とする。この提案は、コンテンツを 配信するウェブサーバの側から見た保証は一切行わない。HTTP/S では現時点でそれが 不可能だからである。
# WACZ Signature File and Format WACZ 形式は [[FRICTIONLESS-DATA-PACKAGE]] の上に構築されている。データパッケージには マニフェストである `datapackage.json` ファイルが含まれ、そこにはデータパッケージ内の 全ファイルのハッシュが記録されている。 署名付き WACZ はさらに `datapackage-digest.json` を含む。これは `datapackage.json` の ハッシュと署名を保持するものである。 (注: この仕様は主として WACZ ファイルを対象に設計されているが、ここで述べる方式は Frictionless Data Package に基づく任意の仕様に応用してもよい)
## Data Package Digest File WACZ ファイルのルートに含まれる `datapackage-digest.json` ファイルは、次の構造を持つ:
{
  "path": "datapackage.json",
  "hash": "sha256:3dd086a0be145d1108bf32a5cac7c4b4c046eb78365792d4bb28e9f43e3c6571",
  "signedData": <Signature Data structure>
}
## Signature Data Format SignatureData 構造は、署名操作の出力である。 SignatureData オブジェクトは WACZ ファイルにつき 1 つしか存在できず、 `datapackage-digest.json` のルートオブジェクトに `signedData` として格納される。 SignatureData オブジェクトは、この節で述べる 2 つの署名形式のいずれかに適合しなければ ならない (MUST): - [Anonymous Signature](#anonymous-signature) - [Domain-Ownership Identity + Signed Timestamp](#domain-ownership-identity-signed-timestamp) SignatureData オブジェクトは、いずれの署名形式にも挙げられていないプロパティを含んでは ならない (MUST NOT)。 ### Anonymous Signature
{
    "hash": "<sha256 hash of datapackage.json>",
    "created": "<ISO 8601 Date>",
    "software": "<string>",
    "version": "<string>",
    "signature": "<base64 encoded signature>",
    "publicKey": "<base64 encoded public key (ECDSA)>"
}
この方式では、WACZ には `publicKey` で署名を検証するのに必要な最小限のものだけが 含まれる。 WACZ の作成者性 (authorship) を検証するには外部の鍵管理が必要であり、それが無い 限りこの署名は匿名である。 現在この方式は、ArchiveWeb.page 拡張機能のような分散型のツールで使われている。 ### Domain-Ownership Identity + Signed Timestamp
{
    "hash": <sha256 hash of datapackage.json>,
    "created": <ISO 8601 Date>,
    "software": <string>,
    "version": <string>,
  
    // domainCert による 'hash' の署名
    "signature": <base64 encoded signature>,
    "domain": <valid hostname>,
    "domainCert": <PEM certificate chain>,
  
    // timestampCert による 'signature' の署名
    "timeSignature": <base64 encoded signature>,
    "timestampCert": <PEM ceriticate chain>,
    
    // 任意: "signature" のためのクロス署名証明書
    "crossSignedCert": <PEM certificate chain>
}
この方式では、特定のドメインの TLS 証明書を作成するのに使われるのと同じ秘密鍵で、 WACZ の署名を作成できる。 WACZ ファイルの作成者は、特定の TLS 証明書の所有者と同一である。それが誰かは 証明書透明性ログ (Certificate Transparency) を通じて調べることができる。 この方式にはさらに、最初の `signature` に対する RFC 3161 タイムスタンプサーバによる `timeSignature` が含まれる。 `timeSignature` にはタイムスタンプが含まれており、署名が指定された作成時刻に近い 時点で作成されたことをさらに保証するよう設計されている。 追加の検証のために、任意の `crossSignedCert` を提供できる。これは、ドメイン証明書が 何らかの理由で危殆化していると判明した場合に、`domainCert` の代わりとして使える。 クロス署名証明書は、必要になったときのために domainCert に依存しない別の信頼経路を 用意する手段にすぎない。 `domainCert`・`timestampCert`・`crossSignedCert` は、検証を助けるために完全な証明書 チェーンを含めることが望ましい。
# Signing `signedData` を生成するために、WACZ の作成者は次の手順を実行できる。 ## Anonymous Signing 最小限の構成として、WACZ の作成者は、自身の公開鍵と署名だけを含む匿名署名の `signedData` を作成できる。 この方式では、WACZ の検証を可能にするために、クライアントが自身の公開鍵を 帯域外 (out-of-band) で配布しなければならない。 ## Domain-Name Identity + Timestamp Signing 2 つ目の例にある signedData を作成するには、クライアントは次を実行しなければ ならない: 1. ECDSA の秘密鍵を生成する。 2. その秘密鍵で署名した証明書要求 (Certificate Request) を作成する。 3. LetsEncrypt のような信頼された CA から、その CSR に対する TLS 証明書を受け取る。 4. 任意: バックアップとして、2 つ目の CA (プライベートな自己署名 CA など) を使い、 2 つ目のクロス署名証明書を生成する。 5. 自身の秘密鍵でハッシュに署名し、1 つ目の署名 (signature) を生成する。 6. RFC 3161 タイムスタンプサーバを使って、直前の署名に署名する (timeSignature) この方式は、WACZ ファイルを安全に作成・署名する「信頼できる第三者 (trusted-third party)」を前提としている。 この方式で想定しているワークフローは次のとおりである。WACZ の作成者は、指定された ドメイン上で動作するアテステーションサーバに対して安全でプライベートな接続を持ち、 そのサーバが要求されたハッシュを観測して署名する。アテステーションサーバへの アクセスは、信頼された WACZ の作成者だけに制限しなければならない。この安全な接続を どう確立するかは、この仕様の範囲外である。
# Verification 署名付き WACZ の検証には、次の手順が関わりうる: 1. WACZ を Frictionless Data Package として検証し、`datapackage.json` の ハッシュが内容と一致することを確認する。 2. `datapackage-digest.json` の `hash` が `datapackage.json` と一致することを 検証する。 3. `datapackage-digest.json` の `signedData` プロパティが[妥当な SignatureData オブジェクト](#signature-data-format)であることを検証する。 ## Anonymous Signature Validation publicKey だけを持つ匿名の `signedData` が与えられた場合: 4. 指定された `hash` に対する `signature` を `publicKey` で検証する。 これで WACZ ファイルは妥当となるが、publicKey 自体は外部の仕組みを使って 検証しなければならない。 ## Domain-Name Identity + Timestamp Validation. ドメイン名署名 + タイムスタンプを持つ署名データが与えられた場合、検証は次のとおり である: 4. `domainCert` 証明書チェーンの最初の証明書を読み、その証明書の公開鍵を使って `signature` が `hash` の妥当な署名であることを検証する。 5. `domain` が `domainCert` TLS 証明書の subjectName と一致することを検証する。 6. `timestampCert` 証明書チェーンの最初の証明書を読み、`timeSignature` が `signature` に対する妥当な RFC 3161 タイムスタンプ署名であることを検証する 7. `created` の日時が、`timeSignature` に含まれる署名済みタイムスタンプから 10 分以内であることを検証する 8. 信頼済みルート一覧と照合して、`domainCert` 証明書チェーンの信頼性を検証する。 (任意で、証明書透明性ログ (Certificate Transparency) で証明書の失効を確認する)。 9. 信頼済みルート一覧と照合して、`timestampCert` 証明書チェーンの信頼性を検証する。 10. 任意: `crossSignedCert` が提供されている場合、それが `domainCert` と同じ公開鍵を 持つことを確認し、このチェーンを信頼済みルート一覧と照合する。あるいは `domainCert` が信頼されていない場合は、`domainCert` の代わりにこの信頼経路を使う。 ## Verification of Partially loaded WACZ 上記の検証手順は、WACZ ファイルが完全に読み込まれていることを前提としている。 しかし WACZ 形式は、個々の HTTP レスポンス (WARC レコード経由) を必要に応じて 部分的に読み込むことに対応している。 部分的・オンデマンドの読み込みでは、WARC ファイルが完全には読み込まれずハッシュと 照合できないため、*手順 1* が変更される。 代わりに、各 WARC レコードについて、読み込んだ WARC レコードのハッシュを CDXJ インデックスに指定されたハッシュと照合する。圧縮された CDXJ インデックスを使う 場合は、各圧縮 CDXJ ブロックのハッシュも IDX インデックスと照合する。(詳細は CDXJ 仕様を参照のこと)。
# Implementations この仕様の実装は次のツールに存在する: * [authsign](https://github.com/webrecorder/authsign) ライブラリは、ドメイン名 identity + タイムスタンプ方式の WACZ `signedData` を作成・検証するための HTTP ベースの API を提供する。このライブラリは、ドメイン証明書をオンデマンドで 生成するために LetsEncrypt サービスを、RFC 3161 タイムスタンプを生成するために [FreeTSA](https://freetsa.org/index_en.php) タイムスタンプサービスを使う。 * [py-wacz](https://github.com/webrecorder/py-wacz) CLI ツールは、ドメイン名 identity + タイムスタンプ付きの WACZ ファイルの生成と検証に使える。署名は `authsign` サーバに API で接続して行い、検証は CLI から直接行える。 * [ArchiveWeb.page](https://archiveweb.page) 拡張機能は、匿名の `signedData` を 持つ署名付き WACZ ファイルを生成する。publicKey は拡張機能の外にはまだ配布されて いない。
# Acknowledgments この仕様の策定は Harvard Law Library Innovation Lab (Harvard LIL) の支援を受け、 同ラボとの協働によって行われた。